Remove support for the beos file format
[binutils-gdb.git] / binutils / readelf.c
blobe3bf68064c1b5d0e5f9e8690becc3f4f308e4faa
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_BOOTDATA: return "OPENBSD_BOOTDATA";
5110 default:
5111 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
5113 const char * result;
5115 switch (filedata->file_header.e_machine)
5117 case EM_AARCH64:
5118 result = get_aarch64_segment_type (p_type);
5119 break;
5120 case EM_ARM:
5121 result = get_arm_segment_type (p_type);
5122 break;
5123 case EM_MIPS:
5124 case EM_MIPS_RS3_LE:
5125 result = get_mips_segment_type (p_type);
5126 break;
5127 case EM_PARISC:
5128 result = get_parisc_segment_type (p_type);
5129 break;
5130 case EM_IA_64:
5131 result = get_ia64_segment_type (p_type);
5132 break;
5133 case EM_TI_C6000:
5134 result = get_tic6x_segment_type (p_type);
5135 break;
5136 case EM_S390:
5137 case EM_S390_OLD:
5138 result = get_s390_segment_type (p_type);
5139 break;
5140 case EM_RISCV:
5141 result = get_riscv_segment_type (p_type);
5142 break;
5143 default:
5144 result = NULL;
5145 break;
5148 if (result != NULL)
5149 return result;
5151 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
5153 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
5155 const char * result = NULL;
5157 switch (filedata->file_header.e_ident[EI_OSABI])
5159 case ELFOSABI_GNU:
5160 case ELFOSABI_FREEBSD:
5161 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
5163 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
5164 result = buff;
5166 break;
5167 case ELFOSABI_HPUX:
5168 result = get_hpux_segment_type (p_type,
5169 filedata->file_header.e_machine);
5170 break;
5171 case ELFOSABI_SOLARIS:
5172 result = get_solaris_segment_type (p_type);
5173 break;
5174 default:
5175 break;
5177 if (result != NULL)
5178 return result;
5180 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
5182 else
5183 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
5185 return buff;
5189 static const char *
5190 get_arc_section_type_name (unsigned int sh_type)
5192 switch (sh_type)
5194 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
5195 default:
5196 break;
5198 return NULL;
5201 static const char *
5202 get_mips_section_type_name (unsigned int sh_type)
5204 switch (sh_type)
5206 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
5207 case SHT_MIPS_MSYM: return "MIPS_MSYM";
5208 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
5209 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
5210 case SHT_MIPS_UCODE: return "MIPS_UCODE";
5211 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
5212 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
5213 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
5214 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
5215 case SHT_MIPS_RELD: return "MIPS_RELD";
5216 case SHT_MIPS_IFACE: return "MIPS_IFACE";
5217 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
5218 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
5219 case SHT_MIPS_SHDR: return "MIPS_SHDR";
5220 case SHT_MIPS_FDESC: return "MIPS_FDESC";
5221 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
5222 case SHT_MIPS_DENSE: return "MIPS_DENSE";
5223 case SHT_MIPS_PDESC: return "MIPS_PDESC";
5224 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
5225 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
5226 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
5227 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
5228 case SHT_MIPS_LINE: return "MIPS_LINE";
5229 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
5230 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
5231 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
5232 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
5233 case SHT_MIPS_DWARF: return "MIPS_DWARF";
5234 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
5235 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
5236 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
5237 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
5238 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
5239 case SHT_MIPS_XLATE: return "MIPS_XLATE";
5240 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
5241 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
5242 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
5243 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
5244 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
5245 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
5246 case SHT_MIPS_XHASH: return "MIPS_XHASH";
5247 default:
5248 break;
5250 return NULL;
5253 static const char *
5254 get_parisc_section_type_name (unsigned int sh_type)
5256 switch (sh_type)
5258 case SHT_PARISC_EXT: return "PARISC_EXT";
5259 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
5260 case SHT_PARISC_DOC: return "PARISC_DOC";
5261 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
5262 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
5263 case SHT_PARISC_STUBS: return "PARISC_STUBS";
5264 case SHT_PARISC_DLKM: return "PARISC_DLKM";
5265 default: return NULL;
5269 static const char *
5270 get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
5272 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
5273 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
5274 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
5276 switch (sh_type)
5278 case SHT_IA_64_EXT: return "IA_64_EXT";
5279 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
5280 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
5281 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
5282 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
5283 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
5284 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
5285 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
5286 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
5287 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
5288 default:
5289 break;
5291 return NULL;
5294 static const char *
5295 get_x86_64_section_type_name (unsigned int sh_type)
5297 switch (sh_type)
5299 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
5300 default: return NULL;
5304 static const char *
5305 get_aarch64_section_type_name (unsigned int sh_type)
5307 switch (sh_type)
5309 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
5310 default: return NULL;
5314 static const char *
5315 get_arm_section_type_name (unsigned int sh_type)
5317 switch (sh_type)
5319 case SHT_ARM_EXIDX: return "ARM_EXIDX";
5320 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
5321 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
5322 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
5323 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
5324 default: return NULL;
5328 static const char *
5329 get_tic6x_section_type_name (unsigned int sh_type)
5331 switch (sh_type)
5333 case SHT_C6000_UNWIND: return "C6000_UNWIND";
5334 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
5335 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
5336 case SHT_TI_ICODE: return "TI_ICODE";
5337 case SHT_TI_XREF: return "TI_XREF";
5338 case SHT_TI_HANDLER: return "TI_HANDLER";
5339 case SHT_TI_INITINFO: return "TI_INITINFO";
5340 case SHT_TI_PHATTRS: return "TI_PHATTRS";
5341 default: return NULL;
5345 static const char *
5346 get_msp430_section_type_name (unsigned int sh_type)
5348 switch (sh_type)
5350 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
5351 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
5352 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
5353 default: return NULL;
5357 static const char *
5358 get_nfp_section_type_name (unsigned int sh_type)
5360 switch (sh_type)
5362 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
5363 case SHT_NFP_INITREG: return "NFP_INITREG";
5364 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
5365 default: return NULL;
5369 static const char *
5370 get_v850_section_type_name (unsigned int sh_type)
5372 switch (sh_type)
5374 case SHT_V850_SCOMMON: return "V850 Small Common";
5375 case SHT_V850_TCOMMON: return "V850 Tiny Common";
5376 case SHT_V850_ZCOMMON: return "V850 Zero Common";
5377 case SHT_RENESAS_IOP: return "RENESAS IOP";
5378 case SHT_RENESAS_INFO: return "RENESAS INFO";
5379 default: return NULL;
5383 static const char *
5384 get_riscv_section_type_name (unsigned int sh_type)
5386 switch (sh_type)
5388 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5389 default: return NULL;
5393 static const char *
5394 get_csky_section_type_name (unsigned int sh_type)
5396 switch (sh_type)
5398 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
5399 default: return NULL;
5403 static const char *
5404 get_section_type_name (Filedata * filedata, unsigned int sh_type)
5406 static char buff[32];
5407 const char * result;
5409 switch (sh_type)
5411 case SHT_NULL: return "NULL";
5412 case SHT_PROGBITS: return "PROGBITS";
5413 case SHT_SYMTAB: return "SYMTAB";
5414 case SHT_STRTAB: return "STRTAB";
5415 case SHT_RELA: return "RELA";
5416 case SHT_RELR: return "RELR";
5417 case SHT_HASH: return "HASH";
5418 case SHT_DYNAMIC: return "DYNAMIC";
5419 case SHT_NOTE: return "NOTE";
5420 case SHT_NOBITS: return "NOBITS";
5421 case SHT_REL: return "REL";
5422 case SHT_SHLIB: return "SHLIB";
5423 case SHT_DYNSYM: return "DYNSYM";
5424 case SHT_INIT_ARRAY: return "INIT_ARRAY";
5425 case SHT_FINI_ARRAY: return "FINI_ARRAY";
5426 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
5427 case SHT_GNU_HASH: return "GNU_HASH";
5428 case SHT_GROUP: return "GROUP";
5429 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
5430 case SHT_GNU_verdef: return "VERDEF";
5431 case SHT_GNU_verneed: return "VERNEED";
5432 case SHT_GNU_versym: return "VERSYM";
5433 case 0x6ffffff0: return "VERSYM";
5434 case 0x6ffffffc: return "VERDEF";
5435 case 0x7ffffffd: return "AUXILIARY";
5436 case 0x7fffffff: return "FILTER";
5437 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
5439 default:
5440 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
5442 switch (filedata->file_header.e_machine)
5444 case EM_ARC:
5445 case EM_ARC_COMPACT:
5446 case EM_ARC_COMPACT2:
5447 case EM_ARC_COMPACT3:
5448 case EM_ARC_COMPACT3_64:
5449 result = get_arc_section_type_name (sh_type);
5450 break;
5451 case EM_MIPS:
5452 case EM_MIPS_RS3_LE:
5453 result = get_mips_section_type_name (sh_type);
5454 break;
5455 case EM_PARISC:
5456 result = get_parisc_section_type_name (sh_type);
5457 break;
5458 case EM_IA_64:
5459 result = get_ia64_section_type_name (filedata, sh_type);
5460 break;
5461 case EM_X86_64:
5462 case EM_L1OM:
5463 case EM_K1OM:
5464 result = get_x86_64_section_type_name (sh_type);
5465 break;
5466 case EM_AARCH64:
5467 result = get_aarch64_section_type_name (sh_type);
5468 break;
5469 case EM_ARM:
5470 result = get_arm_section_type_name (sh_type);
5471 break;
5472 case EM_TI_C6000:
5473 result = get_tic6x_section_type_name (sh_type);
5474 break;
5475 case EM_MSP430:
5476 result = get_msp430_section_type_name (sh_type);
5477 break;
5478 case EM_NFP:
5479 result = get_nfp_section_type_name (sh_type);
5480 break;
5481 case EM_V800:
5482 case EM_V850:
5483 case EM_CYGNUS_V850:
5484 result = get_v850_section_type_name (sh_type);
5485 break;
5486 case EM_RISCV:
5487 result = get_riscv_section_type_name (sh_type);
5488 break;
5489 case EM_CSKY:
5490 result = get_csky_section_type_name (sh_type);
5491 break;
5492 default:
5493 result = NULL;
5494 break;
5497 if (result != NULL)
5498 return result;
5500 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
5502 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
5504 switch (filedata->file_header.e_machine)
5506 case EM_IA_64:
5507 result = get_ia64_section_type_name (filedata, sh_type);
5508 break;
5509 default:
5510 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
5511 result = get_solaris_section_type (sh_type);
5512 else
5514 switch (sh_type)
5516 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
5517 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
5518 case SHT_GNU_HASH: result = "GNU_HASH"; break;
5519 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
5520 default:
5521 result = NULL;
5522 break;
5525 break;
5528 if (result != NULL)
5529 return result;
5531 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
5533 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
5535 switch (filedata->file_header.e_machine)
5537 case EM_V800:
5538 case EM_V850:
5539 case EM_CYGNUS_V850:
5540 result = get_v850_section_type_name (sh_type);
5541 break;
5542 default:
5543 result = NULL;
5544 break;
5547 if (result != NULL)
5548 return result;
5550 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
5552 else
5553 /* This message is probably going to be displayed in a 15
5554 character wide field, so put the hex value first. */
5555 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
5557 return buff;
5561 enum long_option_values
5563 OPTION_DEBUG_DUMP = 512,
5564 OPTION_DYN_SYMS,
5565 OPTION_LTO_SYMS,
5566 OPTION_DWARF_DEPTH,
5567 OPTION_DWARF_START,
5568 OPTION_DWARF_CHECK,
5569 OPTION_CTF_DUMP,
5570 OPTION_CTF_PARENT,
5571 OPTION_CTF_SYMBOLS,
5572 OPTION_CTF_STRINGS,
5573 OPTION_SFRAME_DUMP,
5574 OPTION_WITH_SYMBOL_VERSIONS,
5575 OPTION_RECURSE_LIMIT,
5576 OPTION_NO_RECURSE_LIMIT,
5577 OPTION_NO_DEMANGLING,
5578 OPTION_NO_EXTRA_SYM_INFO,
5579 OPTION_SYM_BASE
5582 static struct option options[] =
5584 /* Note - This table is alpha-sorted on the 'val'
5585 field in order to make adding new options easier. */
5586 {"arch-specific", no_argument, 0, 'A'},
5587 {"all", no_argument, 0, 'a'},
5588 {"demangle", optional_argument, 0, 'C'},
5589 {"archive-index", no_argument, 0, 'c'},
5590 {"use-dynamic", no_argument, 0, 'D'},
5591 {"dynamic", no_argument, 0, 'd'},
5592 {"headers", no_argument, 0, 'e'},
5593 {"section-groups", no_argument, 0, 'g'},
5594 {"help", no_argument, 0, 'H'},
5595 {"file-header", no_argument, 0, 'h'},
5596 {"histogram", no_argument, 0, 'I'},
5597 {"lint", no_argument, 0, 'L'},
5598 {"enable-checks", no_argument, 0, 'L'},
5599 {"program-headers", no_argument, 0, 'l'},
5600 {"segments", no_argument, 0, 'l'},
5601 {"full-section-name",no_argument, 0, 'N'},
5602 {"notes", no_argument, 0, 'n'},
5603 {"process-links", no_argument, 0, 'P'},
5604 {"string-dump", required_argument, 0, 'p'},
5605 {"relocated-dump", required_argument, 0, 'R'},
5606 {"relocs", no_argument, 0, 'r'},
5607 {"section-headers", no_argument, 0, 'S'},
5608 {"sections", no_argument, 0, 'S'},
5609 {"symbols", no_argument, 0, 's'},
5610 {"syms", no_argument, 0, 's'},
5611 {"silent-truncation",no_argument, 0, 'T'},
5612 {"section-details", no_argument, 0, 't'},
5613 {"unicode", required_argument, NULL, 'U'},
5614 {"unwind", no_argument, 0, 'u'},
5615 {"version-info", no_argument, 0, 'V'},
5616 {"version", no_argument, 0, 'v'},
5617 {"wide", no_argument, 0, 'W'},
5618 {"extra-sym-info", no_argument, 0, 'X'},
5619 {"hex-dump", required_argument, 0, 'x'},
5620 {"decompress", no_argument, 0, 'z'},
5622 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
5623 {"no-extra-sym-info",no_argument, 0, OPTION_NO_EXTRA_SYM_INFO},
5624 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5625 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5626 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5627 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
5628 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
5629 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
5630 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5631 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
5632 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
5633 #ifdef ENABLE_LIBCTF
5634 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
5635 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5636 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5637 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
5638 #endif
5639 {"sframe", optional_argument, 0, OPTION_SFRAME_DUMP},
5640 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
5642 {0, no_argument, 0, 0}
5645 static void
5646 usage (FILE * stream)
5648 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5649 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
5650 fprintf (stream, _(" Options are:\n"));
5651 fprintf (stream, _("\
5652 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5653 fprintf (stream, _("\
5654 -h --file-header Display the ELF file header\n"));
5655 fprintf (stream, _("\
5656 -l --program-headers Display the program headers\n"));
5657 fprintf (stream, _("\
5658 --segments An alias for --program-headers\n"));
5659 fprintf (stream, _("\
5660 -S --section-headers Display the sections' header\n"));
5661 fprintf (stream, _("\
5662 --sections An alias for --section-headers\n"));
5663 fprintf (stream, _("\
5664 -g --section-groups Display the section groups\n"));
5665 fprintf (stream, _("\
5666 -t --section-details Display the section details\n"));
5667 fprintf (stream, _("\
5668 -e --headers Equivalent to: -h -l -S\n"));
5669 fprintf (stream, _("\
5670 -s --syms Display the symbol table\n"));
5671 fprintf (stream, _("\
5672 --symbols An alias for --syms\n"));
5673 fprintf (stream, _("\
5674 --dyn-syms Display the dynamic symbol table\n"));
5675 fprintf (stream, _("\
5676 --lto-syms Display LTO symbol tables\n"));
5677 fprintf (stream, _("\
5678 --sym-base=[0|8|10|16] \n\
5679 Force base for symbol sizes. The options are \n\
5680 mixed (the default), octal, decimal, hexadecimal.\n"));
5681 fprintf (stream, _("\
5682 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5683 display_demangler_styles (stream, _("\
5684 STYLE can be "));
5685 fprintf (stream, _("\
5686 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5687 fprintf (stream, _("\
5688 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5689 fprintf (stream, _("\
5690 --no-recurse-limit Disable a demangling recursion limit\n"));
5691 fprintf (stream, _("\
5692 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5693 Display unicode characters as determined by the current locale\n\
5694 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5695 escape sequences, or treat them as invalid and display as\n\
5696 \"{hex sequences}\"\n"));
5697 fprintf (stream, _("\
5698 -X --extra-sym-info Display extra information when showing symbols\n"));
5699 fprintf (stream, _("\
5700 --no-extra-sym-info Do not display extra information when showing symbols (default)\n"));
5701 fprintf (stream, _("\
5702 -n --notes Display the contents of note sections (if present)\n"));
5703 fprintf (stream, _("\
5704 -r --relocs Display the relocations (if present)\n"));
5705 fprintf (stream, _("\
5706 -u --unwind Display the unwind info (if present)\n"));
5707 fprintf (stream, _("\
5708 -d --dynamic Display the dynamic section (if present)\n"));
5709 fprintf (stream, _("\
5710 -V --version-info Display the version sections (if present)\n"));
5711 fprintf (stream, _("\
5712 -A --arch-specific Display architecture specific information (if any)\n"));
5713 fprintf (stream, _("\
5714 -c --archive-index Display the symbol/file index in an archive\n"));
5715 fprintf (stream, _("\
5716 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5717 fprintf (stream, _("\
5718 -L --lint|--enable-checks\n\
5719 Display warning messages for possible problems\n"));
5720 fprintf (stream, _("\
5721 -x --hex-dump=<number|name>\n\
5722 Dump the contents of section <number|name> as bytes\n"));
5723 fprintf (stream, _("\
5724 -p --string-dump=<number|name>\n\
5725 Dump the contents of section <number|name> as strings\n"));
5726 fprintf (stream, _("\
5727 -R --relocated-dump=<number|name>\n\
5728 Dump the relocated contents of section <number|name>\n"));
5729 fprintf (stream, _("\
5730 -z --decompress Decompress section before dumping it\n"));
5731 fprintf (stream, _("\
5732 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5733 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5734 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5735 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5736 U/=trace_info]\n\
5737 Display the contents of DWARF debug sections\n"));
5738 fprintf (stream, _("\
5739 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5740 debuginfo files\n"));
5741 fprintf (stream, _("\
5742 -P --process-links Display the contents of non-debug sections in separate\n\
5743 debuginfo files. (Implies -wK)\n"));
5744 #if DEFAULT_FOR_FOLLOW_LINKS
5745 fprintf (stream, _("\
5746 -wK --debug-dump=follow-links\n\
5747 Follow links to separate debug info files (default)\n"));
5748 fprintf (stream, _("\
5749 -wN --debug-dump=no-follow-links\n\
5750 Do not follow links to separate debug info files\n"));
5751 #else
5752 fprintf (stream, _("\
5753 -wK --debug-dump=follow-links\n\
5754 Follow links to separate debug info files\n"));
5755 fprintf (stream, _("\
5756 -wN --debug-dump=no-follow-links\n\
5757 Do not follow links to separate debug info files\n\
5758 (default)\n"));
5759 #endif
5760 #if HAVE_LIBDEBUGINFOD
5761 fprintf (stream, _("\
5762 -wD --debug-dump=use-debuginfod\n\
5763 When following links, also query debuginfod servers (default)\n"));
5764 fprintf (stream, _("\
5765 -wE --debug-dump=do-not-use-debuginfod\n\
5766 When following links, do not query debuginfod servers\n"));
5767 #endif
5768 fprintf (stream, _("\
5769 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5770 fprintf (stream, _("\
5771 --dwarf-start=N Display DIEs starting at offset N\n"));
5772 #ifdef ENABLE_LIBCTF
5773 fprintf (stream, _("\
5774 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5775 fprintf (stream, _("\
5776 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
5777 fprintf (stream, _("\
5778 --ctf-symbols=<number|name>\n\
5779 Use section <number|name> as the CTF external symtab\n"));
5780 fprintf (stream, _("\
5781 --ctf-strings=<number|name>\n\
5782 Use section <number|name> as the CTF external strtab\n"));
5783 #endif
5784 fprintf (stream, _("\
5785 --sframe[=NAME] Display SFrame info from section NAME, (default '.sframe')\n"));
5787 #ifdef SUPPORT_DISASSEMBLY
5788 fprintf (stream, _("\
5789 -i --instruction-dump=<number|name>\n\
5790 Disassemble the contents of section <number|name>\n"));
5791 #endif
5792 fprintf (stream, _("\
5793 -I --histogram Display histogram of bucket list lengths\n"));
5794 fprintf (stream, _("\
5795 -W --wide Allow output width to exceed 80 characters\n"));
5796 fprintf (stream, _("\
5797 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5798 fprintf (stream, _("\
5799 @<file> Read options from <file>\n"));
5800 fprintf (stream, _("\
5801 -H --help Display this information\n"));
5802 fprintf (stream, _("\
5803 -v --version Display the version number of readelf\n"));
5805 if (REPORT_BUGS_TO[0] && stream == stdout)
5806 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
5808 exit (stream == stdout ? 0 : 1);
5811 /* Record the fact that the user wants the contents of section number
5812 SECTION to be displayed using the method(s) encoded as flags bits
5813 in TYPE. Note, TYPE can be zero if we are creating the array for
5814 the first time. */
5816 static void
5817 request_dump_bynumber (struct dump_data *dumpdata,
5818 unsigned int section, dump_type type)
5820 if (section >= dumpdata->num_dump_sects)
5822 dump_type * new_dump_sects;
5824 new_dump_sects = (dump_type *) calloc (section + 1,
5825 sizeof (* new_dump_sects));
5827 if (new_dump_sects == NULL)
5828 error (_("Out of memory allocating dump request table.\n"));
5829 else
5831 if (dumpdata->dump_sects)
5833 /* Copy current flag settings. */
5834 memcpy (new_dump_sects, dumpdata->dump_sects,
5835 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
5837 free (dumpdata->dump_sects);
5840 dumpdata->dump_sects = new_dump_sects;
5841 dumpdata->num_dump_sects = section + 1;
5845 if (dumpdata->dump_sects)
5846 dumpdata->dump_sects[section] |= type;
5849 /* Request a dump by section name. */
5851 static void
5852 request_dump_byname (const char * section, dump_type type)
5854 struct dump_list_entry * new_request;
5856 new_request = (struct dump_list_entry *)
5857 malloc (sizeof (struct dump_list_entry));
5858 if (!new_request)
5859 error (_("Out of memory allocating dump request table.\n"));
5861 new_request->name = strdup (section);
5862 if (!new_request->name)
5863 error (_("Out of memory allocating dump request table.\n"));
5865 new_request->type = type;
5867 new_request->next = dump_sects_byname;
5868 dump_sects_byname = new_request;
5871 static inline void
5872 request_dump (struct dump_data *dumpdata, dump_type type)
5874 int section;
5875 char * cp;
5877 do_dump = true;
5878 section = strtoul (optarg, & cp, 0);
5880 if (! *cp && section >= 0)
5881 request_dump_bynumber (dumpdata, section, type);
5882 else
5883 request_dump_byname (optarg, type);
5886 static void
5887 parse_args (struct dump_data *dumpdata, int argc, char ** argv)
5889 int c;
5891 if (argc < 2)
5892 usage (stderr);
5894 while ((c = getopt_long
5895 (argc, argv, "ACDHILNPR:STU:VWXacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
5897 switch (c)
5899 case 0:
5900 /* Long options. */
5901 break;
5902 case 'H':
5903 usage (stdout);
5904 break;
5906 case 'a':
5907 do_syms = true;
5908 do_reloc = true;
5909 do_unwind = true;
5910 do_dynamic = true;
5911 do_header = true;
5912 do_sections = true;
5913 do_section_groups = true;
5914 do_segments = true;
5915 do_version = true;
5916 do_histogram = true;
5917 do_arch = true;
5918 do_notes = true;
5919 break;
5921 case 'g':
5922 do_section_groups = true;
5923 break;
5924 case 't':
5925 case 'N':
5926 do_sections = true;
5927 do_section_details = true;
5928 break;
5929 case 'e':
5930 do_header = true;
5931 do_sections = true;
5932 do_segments = true;
5933 break;
5934 case 'A':
5935 do_arch = true;
5936 break;
5937 case 'D':
5938 do_using_dynamic = true;
5939 break;
5940 case 'r':
5941 do_reloc = true;
5942 break;
5943 case 'u':
5944 do_unwind = true;
5945 break;
5946 case 'h':
5947 do_header = true;
5948 break;
5949 case 'l':
5950 do_segments = true;
5951 break;
5952 case 's':
5953 do_syms = true;
5954 break;
5955 case 'S':
5956 do_sections = true;
5957 break;
5958 case 'd':
5959 do_dynamic = true;
5960 break;
5961 case 'I':
5962 do_histogram = true;
5963 break;
5964 case 'n':
5965 do_notes = true;
5966 break;
5967 case 'c':
5968 do_archive_index = true;
5969 break;
5970 case 'L':
5971 do_checks = true;
5972 break;
5973 case 'P':
5974 process_links = true;
5975 do_follow_links = true;
5976 dump_any_debugging = true;
5977 break;
5978 case 'x':
5979 request_dump (dumpdata, HEX_DUMP);
5980 break;
5981 case 'p':
5982 request_dump (dumpdata, STRING_DUMP);
5983 break;
5984 case 'R':
5985 request_dump (dumpdata, RELOC_DUMP);
5986 break;
5987 case 'z':
5988 decompress_dumps = true;
5989 break;
5990 case 'w':
5991 if (optarg == NULL)
5993 do_debugging = true;
5994 do_dump = true;
5995 dump_any_debugging = true;
5996 dwarf_select_sections_all ();
5998 else
6000 do_debugging = false;
6001 if (dwarf_select_sections_by_letters (optarg))
6003 do_dump = true;
6004 dump_any_debugging = true;
6007 break;
6008 case OPTION_DEBUG_DUMP:
6009 if (optarg == NULL)
6011 do_dump = true;
6012 do_debugging = true;
6013 dump_any_debugging = true;
6014 dwarf_select_sections_all ();
6016 else
6018 do_debugging = false;
6019 if (dwarf_select_sections_by_names (optarg))
6021 do_dump = true;
6022 dump_any_debugging = true;
6025 break;
6026 case OPTION_DWARF_DEPTH:
6028 char *cp;
6030 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
6032 break;
6033 case OPTION_DWARF_START:
6035 char *cp;
6037 dwarf_start_die = strtoul (optarg, & cp, 0);
6039 break;
6040 case OPTION_DWARF_CHECK:
6041 dwarf_check = true;
6042 break;
6043 case OPTION_CTF_DUMP:
6044 do_ctf = true;
6045 request_dump (dumpdata, CTF_DUMP);
6046 break;
6047 case OPTION_CTF_SYMBOLS:
6048 free (dump_ctf_symtab_name);
6049 dump_ctf_symtab_name = strdup (optarg);
6050 break;
6051 case OPTION_CTF_STRINGS:
6052 free (dump_ctf_strtab_name);
6053 dump_ctf_strtab_name = strdup (optarg);
6054 break;
6055 case OPTION_CTF_PARENT:
6056 free (dump_ctf_parent_name);
6057 dump_ctf_parent_name = strdup (optarg);
6058 break;
6059 case OPTION_SFRAME_DUMP:
6060 do_sframe = true;
6061 /* Providing section name is optional. request_dump (), however,
6062 thrives on non NULL optarg. Handle it explicitly here. */
6063 if (optarg != NULL)
6064 request_dump (dumpdata, SFRAME_DUMP);
6065 else
6067 do_dump = true;
6068 const char *sframe_sec_name = strdup (".sframe");
6069 request_dump_byname (sframe_sec_name, SFRAME_DUMP);
6071 break;
6072 case OPTION_DYN_SYMS:
6073 do_dyn_syms = true;
6074 break;
6075 case OPTION_LTO_SYMS:
6076 do_lto_syms = true;
6077 break;
6078 case 'X':
6079 extra_sym_info = true;
6080 break;
6081 case OPTION_NO_EXTRA_SYM_INFO:
6082 extra_sym_info = false;
6083 break;
6085 #ifdef SUPPORT_DISASSEMBLY
6086 case 'i':
6087 request_dump (dumpdata, DISASS_DUMP);
6088 break;
6089 #endif
6090 case 'v':
6091 print_version (program_name);
6092 break;
6093 case 'V':
6094 do_version = true;
6095 break;
6096 case 'W':
6097 do_wide = true;
6098 break;
6099 case 'T':
6100 do_not_show_symbol_truncation = true;
6101 break;
6102 case 'C':
6103 do_demangle = true;
6104 if (optarg != NULL)
6106 enum demangling_styles style;
6108 style = cplus_demangle_name_to_style (optarg);
6109 if (style == unknown_demangling)
6110 error (_("unknown demangling style `%s'"), optarg);
6112 cplus_demangle_set_style (style);
6114 break;
6115 case OPTION_NO_DEMANGLING:
6116 do_demangle = false;
6117 break;
6118 case OPTION_RECURSE_LIMIT:
6119 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
6120 break;
6121 case OPTION_NO_RECURSE_LIMIT:
6122 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
6123 break;
6124 case OPTION_WITH_SYMBOL_VERSIONS:
6125 /* Ignored for backward compatibility. */
6126 break;
6128 case 'U':
6129 if (optarg == NULL)
6130 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
6131 else if (streq (optarg, "default") || streq (optarg, "d"))
6132 unicode_display = unicode_default;
6133 else if (streq (optarg, "locale") || streq (optarg, "l"))
6134 unicode_display = unicode_locale;
6135 else if (streq (optarg, "escape") || streq (optarg, "e"))
6136 unicode_display = unicode_escape;
6137 else if (streq (optarg, "invalid") || streq (optarg, "i"))
6138 unicode_display = unicode_invalid;
6139 else if (streq (optarg, "hex") || streq (optarg, "x"))
6140 unicode_display = unicode_hex;
6141 else if (streq (optarg, "highlight") || streq (optarg, "h"))
6142 unicode_display = unicode_highlight;
6143 else
6144 error (_("invalid argument to -U/--unicode: %s"), optarg);
6145 break;
6147 case OPTION_SYM_BASE:
6148 sym_base = 0;
6149 if (optarg != NULL)
6151 sym_base = strtoul (optarg, NULL, 0);
6152 switch (sym_base)
6154 case 0:
6155 case 8:
6156 case 10:
6157 case 16:
6158 break;
6160 default:
6161 sym_base = 0;
6162 break;
6165 break;
6167 default:
6168 /* xgettext:c-format */
6169 error (_("Invalid option '-%c'\n"), c);
6170 /* Fall through. */
6171 case '?':
6172 usage (stderr);
6176 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
6177 && !do_segments && !do_header && !do_dump && !do_version
6178 && !do_histogram && !do_debugging && !do_arch && !do_notes
6179 && !do_section_groups && !do_archive_index
6180 && !do_dyn_syms && !do_lto_syms)
6182 if (do_checks)
6184 check_all = true;
6185 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
6186 do_segments = do_header = do_dump = do_version = true;
6187 do_histogram = do_debugging = do_arch = do_notes = true;
6188 do_section_groups = do_archive_index = do_dyn_syms = true;
6189 do_lto_syms = true;
6191 else
6192 usage (stderr);
6196 static const char *
6197 get_elf_class (unsigned int elf_class)
6199 static char buff[32];
6201 switch (elf_class)
6203 case ELFCLASSNONE: return _("none");
6204 case ELFCLASS32: return "ELF32";
6205 case ELFCLASS64: return "ELF64";
6206 default:
6207 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
6208 return buff;
6212 static const char *
6213 get_data_encoding (unsigned int encoding)
6215 static char buff[32];
6217 switch (encoding)
6219 case ELFDATANONE: return _("none");
6220 case ELFDATA2LSB: return _("2's complement, little endian");
6221 case ELFDATA2MSB: return _("2's complement, big endian");
6222 default:
6223 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
6224 return buff;
6228 static bool
6229 check_magic_number (Filedata * filedata, Elf_Internal_Ehdr * header)
6231 if (header->e_ident[EI_MAG0] == ELFMAG0
6232 && header->e_ident[EI_MAG1] == ELFMAG1
6233 && header->e_ident[EI_MAG2] == ELFMAG2
6234 && header->e_ident[EI_MAG3] == ELFMAG3)
6235 return true;
6237 /* Some compilers produce object files that are not in the ELF file format.
6238 As an aid to users of readelf, try to identify these cases and suggest
6239 alternative tools.
6241 FIXME: It is not clear if all four bytes are used as constant magic
6242 valus by all compilers. It may be necessary to recode this function if
6243 different tools use different length sequences. */
6245 static struct
6247 unsigned char magic[4];
6248 const char * obj_message;
6249 const char * ar_message;
6251 known_magic[] =
6253 { { 'B', 'C', 0xc0, 0xde },
6254 N_("This is a LLVM bitcode file - try using llvm-bcanalyzer\n"),
6255 N_("This is a LLVM bitcode file - try extracting and then using llvm-bcanalyzer\n")
6257 { { 'g', 'o', ' ', 'o' },
6258 N_("This is a GO binary file - try using 'go tool objdump' or 'go tool nm'\n"),
6259 NULL
6262 int i;
6264 for (i = ARRAY_SIZE (known_magic); i--;)
6266 if (header->e_ident[EI_MAG0] == known_magic[i].magic[0]
6267 && header->e_ident[EI_MAG1] == known_magic[i].magic[1]
6268 && header->e_ident[EI_MAG2] == known_magic[i].magic[2]
6269 && header->e_ident[EI_MAG3] == known_magic[i].magic[3])
6271 /* Some compiler's analyzer tools do not handle archives,
6272 so we provide two different kinds of error message. */
6273 if (filedata->archive_file_size > 0
6274 && known_magic[i].ar_message != NULL)
6275 error ("%s", known_magic[i].ar_message);
6276 else
6277 error ("%s", known_magic[i].obj_message);
6278 return false;
6282 error (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
6283 return false;
6286 /* Decode the data held in 'filedata->file_header'. */
6288 static bool
6289 process_file_header (Filedata * filedata)
6291 Elf_Internal_Ehdr * header = & filedata->file_header;
6293 if (! check_magic_number (filedata, header))
6294 return false;
6296 if (! filedata->is_separate)
6297 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
6299 if (do_header)
6301 unsigned i;
6303 if (filedata->is_separate)
6304 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
6305 else
6306 printf (_("ELF Header:\n"));
6307 printf (_(" Magic: "));
6308 for (i = 0; i < EI_NIDENT; i++)
6309 printf ("%2.2x ", header->e_ident[i]);
6310 printf ("\n");
6311 printf (_(" Class: %s\n"),
6312 get_elf_class (header->e_ident[EI_CLASS]));
6313 printf (_(" Data: %s\n"),
6314 get_data_encoding (header->e_ident[EI_DATA]));
6315 printf (_(" Version: %d%s\n"),
6316 header->e_ident[EI_VERSION],
6317 (header->e_ident[EI_VERSION] == EV_CURRENT
6318 ? _(" (current)")
6319 : (header->e_ident[EI_VERSION] != EV_NONE
6320 ? _(" <unknown>")
6321 : "")));
6322 printf (_(" OS/ABI: %s\n"),
6323 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
6324 printf (_(" ABI Version: %d\n"),
6325 header->e_ident[EI_ABIVERSION]);
6326 printf (_(" Type: %s\n"),
6327 get_file_type (filedata));
6328 printf (_(" Machine: %s\n"),
6329 get_machine_name (header->e_machine));
6330 printf (_(" Version: 0x%lx\n"),
6331 header->e_version);
6333 printf (_(" Entry point address: "));
6334 print_vma (header->e_entry, PREFIX_HEX);
6335 printf (_("\n Start of program headers: "));
6336 print_vma (header->e_phoff, DEC);
6337 printf (_(" (bytes into file)\n Start of section headers: "));
6338 print_vma (header->e_shoff, DEC);
6339 printf (_(" (bytes into file)\n"));
6341 printf (_(" Flags: 0x%lx%s\n"),
6342 header->e_flags,
6343 get_machine_flags (filedata, header->e_flags, header->e_machine));
6344 printf (_(" Size of this header: %u (bytes)\n"),
6345 header->e_ehsize);
6346 printf (_(" Size of program headers: %u (bytes)\n"),
6347 header->e_phentsize);
6348 printf (_(" Number of program headers: %u"),
6349 header->e_phnum);
6350 if (filedata->section_headers != NULL
6351 && header->e_phnum == PN_XNUM
6352 && filedata->section_headers[0].sh_info != 0)
6353 printf (" (%u)", filedata->section_headers[0].sh_info);
6354 putc ('\n', stdout);
6355 printf (_(" Size of section headers: %u (bytes)\n"),
6356 header->e_shentsize);
6357 printf (_(" Number of section headers: %u"),
6358 header->e_shnum);
6359 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
6361 header->e_shnum = filedata->section_headers[0].sh_size;
6362 printf (" (%u)", header->e_shnum);
6364 putc ('\n', stdout);
6365 printf (_(" Section header string table index: %u"),
6366 header->e_shstrndx);
6367 if (filedata->section_headers != NULL
6368 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
6370 header->e_shstrndx = filedata->section_headers[0].sh_link;
6371 printf (" (%u)", header->e_shstrndx);
6373 if (header->e_shstrndx != SHN_UNDEF
6374 && header->e_shstrndx >= header->e_shnum)
6376 header->e_shstrndx = SHN_UNDEF;
6377 printf (_(" <corrupt: out of range>"));
6379 putc ('\n', stdout);
6382 if (filedata->section_headers != NULL)
6384 if (header->e_phnum == PN_XNUM
6385 && filedata->section_headers[0].sh_info != 0)
6387 /* Throw away any cached read of PN_XNUM headers. */
6388 free (filedata->program_headers);
6389 filedata->program_headers = NULL;
6390 header->e_phnum = filedata->section_headers[0].sh_info;
6392 if (header->e_shnum == SHN_UNDEF)
6393 header->e_shnum = filedata->section_headers[0].sh_size;
6394 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
6395 header->e_shstrndx = filedata->section_headers[0].sh_link;
6396 if (header->e_shstrndx >= header->e_shnum)
6397 header->e_shstrndx = SHN_UNDEF;
6400 return true;
6403 /* Read in the program headers from FILEDATA and store them in PHEADERS.
6404 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
6406 static bool
6407 get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
6409 Elf32_External_Phdr * phdrs;
6410 Elf32_External_Phdr * external;
6411 Elf_Internal_Phdr * internal;
6412 unsigned int i;
6413 unsigned int size = filedata->file_header.e_phentsize;
6414 unsigned int num = filedata->file_header.e_phnum;
6416 /* PR binutils/17531: Cope with unexpected section header sizes. */
6417 if (size == 0 || num == 0)
6418 return false;
6419 if (size < sizeof * phdrs)
6421 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
6422 return false;
6424 if (size > sizeof * phdrs)
6425 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
6427 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
6428 size, num, _("program headers"));
6429 if (phdrs == NULL)
6430 return false;
6432 for (i = 0, internal = pheaders, external = phdrs;
6433 i < filedata->file_header.e_phnum;
6434 i++, internal++, external++)
6436 internal->p_type = BYTE_GET (external->p_type);
6437 internal->p_offset = BYTE_GET (external->p_offset);
6438 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6439 internal->p_paddr = BYTE_GET (external->p_paddr);
6440 internal->p_filesz = BYTE_GET (external->p_filesz);
6441 internal->p_memsz = BYTE_GET (external->p_memsz);
6442 internal->p_flags = BYTE_GET (external->p_flags);
6443 internal->p_align = BYTE_GET (external->p_align);
6446 free (phdrs);
6447 return true;
6450 /* Read in the program headers from FILEDATA and store them in PHEADERS.
6451 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
6453 static bool
6454 get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
6456 Elf64_External_Phdr * phdrs;
6457 Elf64_External_Phdr * external;
6458 Elf_Internal_Phdr * internal;
6459 unsigned int i;
6460 unsigned int size = filedata->file_header.e_phentsize;
6461 unsigned int num = filedata->file_header.e_phnum;
6463 /* PR binutils/17531: Cope with unexpected section header sizes. */
6464 if (size == 0 || num == 0)
6465 return false;
6466 if (size < sizeof * phdrs)
6468 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
6469 return false;
6471 if (size > sizeof * phdrs)
6472 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
6474 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
6475 size, num, _("program headers"));
6476 if (!phdrs)
6477 return false;
6479 for (i = 0, internal = pheaders, external = phdrs;
6480 i < filedata->file_header.e_phnum;
6481 i++, internal++, external++)
6483 internal->p_type = BYTE_GET (external->p_type);
6484 internal->p_flags = BYTE_GET (external->p_flags);
6485 internal->p_offset = BYTE_GET (external->p_offset);
6486 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6487 internal->p_paddr = BYTE_GET (external->p_paddr);
6488 internal->p_filesz = BYTE_GET (external->p_filesz);
6489 internal->p_memsz = BYTE_GET (external->p_memsz);
6490 internal->p_align = BYTE_GET (external->p_align);
6493 free (phdrs);
6494 return true;
6497 /* Returns TRUE if the program headers were read into `program_headers'. */
6499 static bool
6500 get_program_headers (Filedata * filedata)
6502 Elf_Internal_Phdr * phdrs;
6504 /* Check cache of prior read. */
6505 if (filedata->program_headers != NULL)
6506 return true;
6508 /* Be kind to memory checkers by looking for
6509 e_phnum values which we know must be invalid. */
6510 if (filedata->file_header.e_phnum
6511 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
6512 >= filedata->file_size)
6514 error (_("Too many program headers - %#x - the file is not that big\n"),
6515 filedata->file_header.e_phnum);
6516 return false;
6519 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
6520 sizeof (Elf_Internal_Phdr));
6521 if (phdrs == NULL)
6523 error (_("Out of memory reading %u program headers\n"),
6524 filedata->file_header.e_phnum);
6525 return false;
6528 if (is_32bit_elf
6529 ? get_32bit_program_headers (filedata, phdrs)
6530 : get_64bit_program_headers (filedata, phdrs))
6532 filedata->program_headers = phdrs;
6533 return true;
6536 free (phdrs);
6537 return false;
6540 /* Print program header info and locate dynamic section. */
6542 static void
6543 process_program_headers (Filedata * filedata)
6545 Elf_Internal_Phdr * segment;
6546 unsigned int i;
6547 Elf_Internal_Phdr * previous_load = NULL;
6549 if (filedata->file_header.e_phnum == 0)
6551 /* PR binutils/12467. */
6552 if (filedata->file_header.e_phoff != 0)
6553 warn (_("possibly corrupt ELF header - it has a non-zero program"
6554 " header offset, but no program headers\n"));
6555 else if (do_segments)
6557 if (filedata->is_separate)
6558 printf (_("\nThere are no program headers in linked file '%s'.\n"),
6559 filedata->file_name);
6560 else
6561 printf (_("\nThere are no program headers in this file.\n"));
6563 goto no_headers;
6566 if (do_segments && !do_header)
6568 if (filedata->is_separate)
6569 printf ("\nIn linked file '%s' the ELF file type is %s\n",
6570 filedata->file_name, get_file_type (filedata));
6571 else
6572 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
6573 printf (_("Entry point 0x%" PRIx64 "\n"),
6574 filedata->file_header.e_entry);
6575 printf (ngettext ("There is %d program header,"
6576 " starting at offset %" PRIu64 "\n",
6577 "There are %d program headers,"
6578 " starting at offset %" PRIu64 "\n",
6579 filedata->file_header.e_phnum),
6580 filedata->file_header.e_phnum,
6581 filedata->file_header.e_phoff);
6584 if (! get_program_headers (filedata))
6585 goto no_headers;
6587 if (do_segments)
6589 if (filedata->file_header.e_phnum > 1)
6590 printf (_("\nProgram Headers:\n"));
6591 else
6592 printf (_("\nProgram Headers:\n"));
6594 if (is_32bit_elf)
6595 printf
6596 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
6597 else if (do_wide)
6598 printf
6599 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
6600 else
6602 printf
6603 (_(" Type Offset VirtAddr PhysAddr\n"));
6604 printf
6605 (_(" FileSiz MemSiz Flags Align\n"));
6609 uint64_t dynamic_addr = 0;
6610 uint64_t dynamic_size = 0;
6611 for (i = 0, segment = filedata->program_headers;
6612 i < filedata->file_header.e_phnum;
6613 i++, segment++)
6615 if (do_segments)
6617 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
6619 if (is_32bit_elf)
6621 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6622 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
6623 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
6624 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
6625 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
6626 printf ("%c%c%c ",
6627 (segment->p_flags & PF_R ? 'R' : ' '),
6628 (segment->p_flags & PF_W ? 'W' : ' '),
6629 (segment->p_flags & PF_X ? 'E' : ' '));
6630 printf ("%#lx", (unsigned long) segment->p_align);
6632 else if (do_wide)
6634 if ((unsigned long) segment->p_offset == segment->p_offset)
6635 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6636 else
6638 print_vma (segment->p_offset, FULL_HEX);
6639 putchar (' ');
6642 print_vma (segment->p_vaddr, FULL_HEX);
6643 putchar (' ');
6644 print_vma (segment->p_paddr, FULL_HEX);
6645 putchar (' ');
6647 if ((unsigned long) segment->p_filesz == segment->p_filesz)
6648 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
6649 else
6651 print_vma (segment->p_filesz, FULL_HEX);
6652 putchar (' ');
6655 if ((unsigned long) segment->p_memsz == segment->p_memsz)
6656 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
6657 else
6659 print_vma (segment->p_memsz, FULL_HEX);
6662 printf (" %c%c%c ",
6663 (segment->p_flags & PF_R ? 'R' : ' '),
6664 (segment->p_flags & PF_W ? 'W' : ' '),
6665 (segment->p_flags & PF_X ? 'E' : ' '));
6667 if ((unsigned long) segment->p_align == segment->p_align)
6668 printf ("%#lx", (unsigned long) segment->p_align);
6669 else
6671 print_vma (segment->p_align, PREFIX_HEX);
6674 else
6676 print_vma (segment->p_offset, FULL_HEX);
6677 putchar (' ');
6678 print_vma (segment->p_vaddr, FULL_HEX);
6679 putchar (' ');
6680 print_vma (segment->p_paddr, FULL_HEX);
6681 printf ("\n ");
6682 print_vma (segment->p_filesz, FULL_HEX);
6683 putchar (' ');
6684 print_vma (segment->p_memsz, FULL_HEX);
6685 printf (" %c%c%c ",
6686 (segment->p_flags & PF_R ? 'R' : ' '),
6687 (segment->p_flags & PF_W ? 'W' : ' '),
6688 (segment->p_flags & PF_X ? 'E' : ' '));
6689 print_vma (segment->p_align, PREFIX_HEX);
6692 putc ('\n', stdout);
6695 switch (segment->p_type)
6697 case PT_LOAD:
6698 #if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
6699 required by the ELF standard, several programs, including the Linux
6700 kernel, make use of non-ordered segments. */
6701 if (previous_load
6702 && previous_load->p_vaddr > segment->p_vaddr)
6703 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
6704 #endif
6705 if (segment->p_memsz < segment->p_filesz)
6706 error (_("the segment's file size is larger than its memory size\n"));
6707 previous_load = segment;
6708 break;
6710 case PT_PHDR:
6711 /* PR 20815 - Verify that the program header is loaded into memory. */
6712 if (i > 0 && previous_load != NULL)
6713 error (_("the PHDR segment must occur before any LOAD segment\n"));
6714 if (filedata->file_header.e_machine != EM_PARISC)
6716 unsigned int j;
6718 for (j = 1; j < filedata->file_header.e_phnum; j++)
6720 Elf_Internal_Phdr *load = filedata->program_headers + j;
6721 if (load->p_type == PT_LOAD
6722 && load->p_offset <= segment->p_offset
6723 && (load->p_offset + load->p_filesz
6724 >= segment->p_offset + segment->p_filesz)
6725 && load->p_vaddr <= segment->p_vaddr
6726 && (load->p_vaddr + load->p_filesz
6727 >= segment->p_vaddr + segment->p_filesz))
6728 break;
6730 if (j == filedata->file_header.e_phnum)
6731 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6733 break;
6735 case PT_DYNAMIC:
6736 if (dynamic_addr)
6737 error (_("more than one dynamic segment\n"));
6739 /* By default, assume that the .dynamic section is the first
6740 section in the DYNAMIC segment. */
6741 dynamic_addr = segment->p_offset;
6742 dynamic_size = segment->p_filesz;
6744 /* Try to locate the .dynamic section. If there is
6745 a section header table, we can easily locate it. */
6746 if (filedata->section_headers != NULL)
6748 Elf_Internal_Shdr * sec;
6750 sec = find_section (filedata, ".dynamic");
6751 if (sec == NULL || sec->sh_size == 0)
6753 /* A corresponding .dynamic section is expected, but on
6754 IA-64/OpenVMS it is OK for it to be missing. */
6755 if (!is_ia64_vms (filedata))
6756 error (_("no .dynamic section in the dynamic segment\n"));
6757 break;
6760 if (sec->sh_type == SHT_NOBITS)
6762 dynamic_addr = 0;
6763 dynamic_size = 0;
6764 break;
6767 dynamic_addr = sec->sh_offset;
6768 dynamic_size = sec->sh_size;
6770 /* The PT_DYNAMIC segment, which is used by the run-time
6771 loader, should exactly match the .dynamic section. */
6772 if (do_checks
6773 && (dynamic_addr != segment->p_offset
6774 || dynamic_size != segment->p_filesz))
6775 warn (_("\
6776 the .dynamic section is not the same as the dynamic segment\n"));
6779 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6780 segment. Check this after matching against the section headers
6781 so we don't warn on debuginfo file (which have NOBITS .dynamic
6782 sections). */
6783 if (dynamic_addr > filedata->file_size
6784 || (dynamic_size > filedata->file_size - dynamic_addr))
6786 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
6787 dynamic_addr = 0;
6788 dynamic_size = 0;
6790 break;
6792 case PT_INTERP:
6793 if (segment->p_offset >= filedata->file_size
6794 || segment->p_filesz > filedata->file_size - segment->p_offset
6795 || segment->p_filesz - 1 >= (size_t) -2
6796 || fseek64 (filedata->handle,
6797 filedata->archive_file_offset + segment->p_offset,
6798 SEEK_SET))
6799 error (_("Unable to find program interpreter name\n"));
6800 else
6802 size_t len = segment->p_filesz;
6803 free (filedata->program_interpreter);
6804 filedata->program_interpreter = xmalloc (len + 1);
6805 len = fread (filedata->program_interpreter, 1, len,
6806 filedata->handle);
6807 filedata->program_interpreter[len] = 0;
6809 if (do_segments)
6810 printf (_(" [Requesting program interpreter: %s]\n"),
6811 filedata->program_interpreter);
6813 break;
6817 if (do_segments
6818 && filedata->section_headers != NULL
6819 && filedata->string_table != NULL)
6821 printf (_("\n Section to Segment mapping:\n"));
6822 printf (_(" Segment Sections...\n"));
6824 for (i = 0; i < filedata->file_header.e_phnum; i++)
6826 unsigned int j;
6827 Elf_Internal_Shdr * section;
6829 segment = filedata->program_headers + i;
6830 section = filedata->section_headers + 1;
6832 printf (" %2.2d ", i);
6834 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
6836 if (!ELF_TBSS_SPECIAL (section, segment)
6837 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
6838 printf ("%s ", printable_section_name (filedata, section));
6841 putc ('\n',stdout);
6845 filedata->dynamic_addr = dynamic_addr;
6846 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6847 return;
6849 no_headers:
6850 filedata->dynamic_addr = 0;
6851 filedata->dynamic_size = 1;
6855 /* Find the file offset corresponding to VMA by using the program headers. */
6857 static int64_t
6858 offset_from_vma (Filedata * filedata, uint64_t vma, uint64_t size)
6860 Elf_Internal_Phdr * seg;
6862 if (! get_program_headers (filedata))
6864 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6865 return (long) vma;
6868 for (seg = filedata->program_headers;
6869 seg < filedata->program_headers + filedata->file_header.e_phnum;
6870 ++seg)
6872 if (seg->p_type != PT_LOAD)
6873 continue;
6875 if (vma >= (seg->p_vaddr & -seg->p_align)
6876 && vma + size <= seg->p_vaddr + seg->p_filesz)
6877 return vma - seg->p_vaddr + seg->p_offset;
6880 warn (_("Virtual address %#" PRIx64
6881 " not located in any PT_LOAD segment.\n"), vma);
6882 return vma;
6886 /* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6887 If PROBE is true, this is just a probe and we do not generate any error
6888 messages if the load fails. */
6890 static bool
6891 get_32bit_section_headers (Filedata * filedata, bool probe)
6893 Elf32_External_Shdr * shdrs;
6894 Elf_Internal_Shdr * internal;
6895 unsigned int i;
6896 unsigned int size = filedata->file_header.e_shentsize;
6897 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
6899 /* PR binutils/17531: Cope with unexpected section header sizes. */
6900 if (size == 0 || num == 0)
6901 return false;
6903 /* The section header cannot be at the start of the file - that is
6904 where the ELF file header is located. A file with absolutely no
6905 sections in it will use a shoff of 0. */
6906 if (filedata->file_header.e_shoff == 0)
6907 return false;
6909 if (size < sizeof * shdrs)
6911 if (! probe)
6912 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
6913 return false;
6915 if (!probe && size > sizeof * shdrs)
6916 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
6918 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
6919 size, num,
6920 probe ? NULL : _("section headers"));
6921 if (shdrs == NULL)
6922 return false;
6924 filedata->section_headers = (Elf_Internal_Shdr *)
6925 cmalloc (num, sizeof (Elf_Internal_Shdr));
6926 if (filedata->section_headers == NULL)
6928 if (!probe)
6929 error (_("Out of memory reading %u section headers\n"), num);
6930 free (shdrs);
6931 return false;
6934 for (i = 0, internal = filedata->section_headers;
6935 i < num;
6936 i++, internal++)
6938 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6939 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6940 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6941 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6942 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6943 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6944 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6945 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6946 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6947 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
6948 if (!probe && internal->sh_link > num)
6949 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6950 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6951 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
6954 free (shdrs);
6955 return true;
6958 /* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6960 static bool
6961 get_64bit_section_headers (Filedata * filedata, bool probe)
6963 Elf64_External_Shdr * shdrs;
6964 Elf_Internal_Shdr * internal;
6965 unsigned int i;
6966 unsigned int size = filedata->file_header.e_shentsize;
6967 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
6969 /* PR binutils/17531: Cope with unexpected section header sizes. */
6970 if (size == 0 || num == 0)
6971 return false;
6973 /* The section header cannot be at the start of the file - that is
6974 where the ELF file header is located. A file with absolutely no
6975 sections in it will use a shoff of 0. */
6976 if (filedata->file_header.e_shoff == 0)
6977 return false;
6979 if (size < sizeof * shdrs)
6981 if (! probe)
6982 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
6983 return false;
6986 if (! probe && size > sizeof * shdrs)
6987 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
6989 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6990 filedata->file_header.e_shoff,
6991 size, num,
6992 probe ? NULL : _("section headers"));
6993 if (shdrs == NULL)
6994 return false;
6996 filedata->section_headers = (Elf_Internal_Shdr *)
6997 cmalloc (num, sizeof (Elf_Internal_Shdr));
6998 if (filedata->section_headers == NULL)
7000 if (! probe)
7001 error (_("Out of memory reading %u section headers\n"), num);
7002 free (shdrs);
7003 return false;
7006 for (i = 0, internal = filedata->section_headers;
7007 i < num;
7008 i++, internal++)
7010 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
7011 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
7012 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
7013 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
7014 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
7015 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
7016 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
7017 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
7018 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
7019 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
7020 if (!probe && internal->sh_link > num)
7021 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
7022 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
7023 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
7026 free (shdrs);
7027 return true;
7030 static bool
7031 get_section_headers (Filedata *filedata, bool probe)
7033 if (filedata->section_headers != NULL)
7034 return true;
7036 if (is_32bit_elf)
7037 return get_32bit_section_headers (filedata, probe);
7038 else
7039 return get_64bit_section_headers (filedata, probe);
7042 static Elf_Internal_Sym *
7043 get_32bit_elf_symbols (Filedata *filedata,
7044 Elf_Internal_Shdr *section,
7045 uint64_t *num_syms_return)
7047 uint64_t number = 0;
7048 Elf32_External_Sym * esyms = NULL;
7049 Elf_External_Sym_Shndx * shndx = NULL;
7050 Elf_Internal_Sym * isyms = NULL;
7051 Elf_Internal_Sym * psym;
7052 unsigned int j;
7053 elf_section_list * entry;
7055 if (section->sh_size == 0)
7057 if (num_syms_return != NULL)
7058 * num_syms_return = 0;
7059 return NULL;
7062 /* Run some sanity checks first. */
7063 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
7065 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
7066 printable_section_name (filedata, section),
7067 section->sh_entsize);
7068 goto exit_point;
7071 if (section->sh_size > filedata->file_size)
7073 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
7074 printable_section_name (filedata, section),
7075 section->sh_size);
7076 goto exit_point;
7079 number = section->sh_size / section->sh_entsize;
7081 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
7083 error (_("Size (%#" PRIx64 ") of section %s "
7084 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7085 section->sh_size,
7086 printable_section_name (filedata, section),
7087 section->sh_entsize);
7088 goto exit_point;
7091 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
7092 section->sh_size, _("symbols"));
7093 if (esyms == NULL)
7094 goto exit_point;
7096 shndx = NULL;
7097 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
7099 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
7100 continue;
7102 if (shndx != NULL)
7104 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7105 free (shndx);
7108 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7109 entry->hdr->sh_offset,
7110 1, entry->hdr->sh_size,
7111 _("symbol table section indices"));
7112 if (shndx == NULL)
7113 goto exit_point;
7115 /* PR17531: file: heap-buffer-overflow */
7116 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7118 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
7119 printable_section_name (filedata, entry->hdr),
7120 entry->hdr->sh_size,
7121 section->sh_size);
7122 goto exit_point;
7126 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
7128 if (isyms == NULL)
7130 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
7131 goto exit_point;
7134 for (j = 0, psym = isyms; j < number; j++, psym++)
7136 psym->st_name = BYTE_GET (esyms[j].st_name);
7137 psym->st_value = BYTE_GET (esyms[j].st_value);
7138 psym->st_size = BYTE_GET (esyms[j].st_size);
7139 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
7140 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
7141 psym->st_shndx
7142 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
7143 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7144 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
7145 psym->st_info = BYTE_GET (esyms[j].st_info);
7146 psym->st_other = BYTE_GET (esyms[j].st_other);
7149 exit_point:
7150 free (shndx);
7151 free (esyms);
7153 if (num_syms_return != NULL)
7154 * num_syms_return = isyms == NULL ? 0 : number;
7156 return isyms;
7159 static Elf_Internal_Sym *
7160 get_64bit_elf_symbols (Filedata *filedata,
7161 Elf_Internal_Shdr *section,
7162 uint64_t *num_syms_return)
7164 uint64_t number = 0;
7165 Elf64_External_Sym * esyms = NULL;
7166 Elf_External_Sym_Shndx * shndx = NULL;
7167 Elf_Internal_Sym * isyms = NULL;
7168 Elf_Internal_Sym * psym;
7169 unsigned int j;
7170 elf_section_list * entry;
7172 if (section->sh_size == 0)
7174 if (num_syms_return != NULL)
7175 * num_syms_return = 0;
7176 return NULL;
7179 /* Run some sanity checks first. */
7180 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
7182 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
7183 printable_section_name (filedata, section),
7184 section->sh_entsize);
7185 goto exit_point;
7188 if (section->sh_size > filedata->file_size)
7190 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
7191 printable_section_name (filedata, section),
7192 section->sh_size);
7193 goto exit_point;
7196 number = section->sh_size / section->sh_entsize;
7198 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
7200 error (_("Size (%#" PRIx64 ") of section %s "
7201 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7202 section->sh_size,
7203 printable_section_name (filedata, section),
7204 section->sh_entsize);
7205 goto exit_point;
7208 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
7209 section->sh_size, _("symbols"));
7210 if (!esyms)
7211 goto exit_point;
7213 shndx = NULL;
7214 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
7216 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
7217 continue;
7219 if (shndx != NULL)
7221 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7222 free (shndx);
7225 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7226 entry->hdr->sh_offset,
7227 1, entry->hdr->sh_size,
7228 _("symbol table section indices"));
7229 if (shndx == NULL)
7230 goto exit_point;
7232 /* PR17531: file: heap-buffer-overflow */
7233 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7235 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
7236 printable_section_name (filedata, entry->hdr),
7237 entry->hdr->sh_size,
7238 section->sh_size);
7239 goto exit_point;
7243 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
7245 if (isyms == NULL)
7247 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
7248 goto exit_point;
7251 for (j = 0, psym = isyms; j < number; j++, psym++)
7253 psym->st_name = BYTE_GET (esyms[j].st_name);
7254 psym->st_info = BYTE_GET (esyms[j].st_info);
7255 psym->st_other = BYTE_GET (esyms[j].st_other);
7256 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
7258 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
7259 psym->st_shndx
7260 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
7261 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7262 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
7264 psym->st_value = BYTE_GET (esyms[j].st_value);
7265 psym->st_size = BYTE_GET (esyms[j].st_size);
7268 exit_point:
7269 free (shndx);
7270 free (esyms);
7272 if (num_syms_return != NULL)
7273 * num_syms_return = isyms == NULL ? 0 : number;
7275 return isyms;
7278 static Elf_Internal_Sym *
7279 get_elf_symbols (Filedata *filedata,
7280 Elf_Internal_Shdr *section,
7281 uint64_t *num_syms_return)
7283 if (is_32bit_elf)
7284 return get_32bit_elf_symbols (filedata, section, num_syms_return);
7285 else
7286 return get_64bit_elf_symbols (filedata, section, num_syms_return);
7289 static const char *
7290 get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
7292 static char buff[1024];
7293 char * p = buff;
7294 unsigned int field_size = is_32bit_elf ? 8 : 16;
7295 signed int sindex;
7296 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
7297 uint64_t os_flags = 0;
7298 uint64_t proc_flags = 0;
7299 uint64_t unknown_flags = 0;
7300 static const struct
7302 const char * str;
7303 unsigned int len;
7305 flags [] =
7307 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
7308 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
7309 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
7310 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
7311 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
7312 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
7313 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
7314 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
7315 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
7316 /* 9 */ { STRING_COMMA_LEN ("TLS") },
7317 /* IA-64 specific. */
7318 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
7319 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
7320 /* IA-64 OpenVMS specific. */
7321 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
7322 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
7323 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
7324 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
7325 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
7326 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
7327 /* Generic. */
7328 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
7329 /* SPARC specific. */
7330 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
7331 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
7332 /* ARM specific. */
7333 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
7334 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
7335 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
7336 /* GNU specific. */
7337 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
7338 /* VLE specific. */
7339 /* 25 */ { STRING_COMMA_LEN ("VLE") },
7340 /* GNU specific. */
7341 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
7344 if (do_section_details)
7345 p += sprintf (p, "[%*.*lx]: ",
7346 field_size, field_size, (unsigned long) sh_flags);
7348 while (sh_flags)
7350 uint64_t flag;
7352 flag = sh_flags & - sh_flags;
7353 sh_flags &= ~ flag;
7355 if (do_section_details)
7357 switch (flag)
7359 case SHF_WRITE: sindex = 0; break;
7360 case SHF_ALLOC: sindex = 1; break;
7361 case SHF_EXECINSTR: sindex = 2; break;
7362 case SHF_MERGE: sindex = 3; break;
7363 case SHF_STRINGS: sindex = 4; break;
7364 case SHF_INFO_LINK: sindex = 5; break;
7365 case SHF_LINK_ORDER: sindex = 6; break;
7366 case SHF_OS_NONCONFORMING: sindex = 7; break;
7367 case SHF_GROUP: sindex = 8; break;
7368 case SHF_TLS: sindex = 9; break;
7369 case SHF_EXCLUDE: sindex = 18; break;
7370 case SHF_COMPRESSED: sindex = 20; break;
7372 default:
7373 sindex = -1;
7374 switch (filedata->file_header.e_machine)
7376 case EM_IA_64:
7377 if (flag == SHF_IA_64_SHORT)
7378 sindex = 10;
7379 else if (flag == SHF_IA_64_NORECOV)
7380 sindex = 11;
7381 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
7382 switch (flag)
7384 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
7385 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
7386 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
7387 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
7388 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
7389 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
7390 default: break;
7392 break;
7394 case EM_386:
7395 case EM_IAMCU:
7396 case EM_X86_64:
7397 case EM_L1OM:
7398 case EM_K1OM:
7399 case EM_OLD_SPARCV9:
7400 case EM_SPARC32PLUS:
7401 case EM_SPARCV9:
7402 case EM_SPARC:
7403 if (flag == SHF_ORDERED)
7404 sindex = 19;
7405 break;
7407 case EM_ARM:
7408 switch (flag)
7410 case SHF_ENTRYSECT: sindex = 21; break;
7411 case SHF_ARM_PURECODE: sindex = 22; break;
7412 case SHF_COMDEF: sindex = 23; break;
7413 default: break;
7415 break;
7416 case EM_PPC:
7417 if (flag == SHF_PPC_VLE)
7418 sindex = 25;
7419 break;
7420 default:
7421 break;
7424 switch (filedata->file_header.e_ident[EI_OSABI])
7426 case ELFOSABI_GNU:
7427 case ELFOSABI_FREEBSD:
7428 if (flag == SHF_GNU_RETAIN)
7429 sindex = 26;
7430 /* Fall through */
7431 case ELFOSABI_NONE:
7432 if (flag == SHF_GNU_MBIND)
7433 /* We should not recognize SHF_GNU_MBIND for
7434 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7435 not set the EI_OSABI header byte. */
7436 sindex = 24;
7437 break;
7438 default:
7439 break;
7441 break;
7444 if (sindex != -1)
7446 if (p != buff + field_size + 4)
7448 if (size < (10 + 2))
7450 warn (_("Internal error: not enough buffer room for section flag info"));
7451 return _("<unknown>");
7453 size -= 2;
7454 *p++ = ',';
7455 *p++ = ' ';
7458 size -= flags [sindex].len;
7459 p = stpcpy (p, flags [sindex].str);
7461 else if (flag & SHF_MASKOS)
7462 os_flags |= flag;
7463 else if (flag & SHF_MASKPROC)
7464 proc_flags |= flag;
7465 else
7466 unknown_flags |= flag;
7468 else
7470 switch (flag)
7472 case SHF_WRITE: *p = 'W'; break;
7473 case SHF_ALLOC: *p = 'A'; break;
7474 case SHF_EXECINSTR: *p = 'X'; break;
7475 case SHF_MERGE: *p = 'M'; break;
7476 case SHF_STRINGS: *p = 'S'; break;
7477 case SHF_INFO_LINK: *p = 'I'; break;
7478 case SHF_LINK_ORDER: *p = 'L'; break;
7479 case SHF_OS_NONCONFORMING: *p = 'O'; break;
7480 case SHF_GROUP: *p = 'G'; break;
7481 case SHF_TLS: *p = 'T'; break;
7482 case SHF_EXCLUDE: *p = 'E'; break;
7483 case SHF_COMPRESSED: *p = 'C'; break;
7485 default:
7486 if ((filedata->file_header.e_machine == EM_X86_64
7487 || filedata->file_header.e_machine == EM_L1OM
7488 || filedata->file_header.e_machine == EM_K1OM)
7489 && flag == SHF_X86_64_LARGE)
7490 *p = 'l';
7491 else if (filedata->file_header.e_machine == EM_ARM
7492 && flag == SHF_ARM_PURECODE)
7493 *p = 'y';
7494 else if (filedata->file_header.e_machine == EM_PPC
7495 && flag == SHF_PPC_VLE)
7496 *p = 'v';
7497 else if (flag & SHF_MASKOS)
7499 switch (filedata->file_header.e_ident[EI_OSABI])
7501 case ELFOSABI_GNU:
7502 case ELFOSABI_FREEBSD:
7503 if (flag == SHF_GNU_RETAIN)
7505 *p = 'R';
7506 break;
7508 /* Fall through */
7509 case ELFOSABI_NONE:
7510 if (flag == SHF_GNU_MBIND)
7512 /* We should not recognize SHF_GNU_MBIND for
7513 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7514 not set the EI_OSABI header byte. */
7515 *p = 'D';
7516 break;
7518 /* Fall through */
7519 default:
7520 *p = 'o';
7521 sh_flags &= ~SHF_MASKOS;
7522 break;
7525 else if (flag & SHF_MASKPROC)
7527 *p = 'p';
7528 sh_flags &= ~ SHF_MASKPROC;
7530 else
7531 *p = 'x';
7532 break;
7534 p++;
7538 if (do_section_details)
7540 if (os_flags)
7542 if (p != buff + field_size + 4)
7544 if (size < 2 + 5 + field_size + 1)
7546 warn (_("Internal error: not enough buffer room for section flag info"));
7547 return _("<unknown>");
7549 size -= 2;
7550 *p++ = ',';
7551 *p++ = ' ';
7553 size -= 5 + field_size;
7554 p += sprintf (p, "OS (%*.*lx)", field_size, field_size,
7555 (unsigned long) os_flags);
7557 if (proc_flags)
7559 if (p != buff + field_size + 4)
7561 if (size < 2 + 7 + field_size + 1)
7563 warn (_("Internal error: not enough buffer room for section flag info"));
7564 return _("<unknown>");
7566 size -= 2;
7567 *p++ = ',';
7568 *p++ = ' ';
7570 size -= 7 + field_size;
7571 p += sprintf (p, "PROC (%*.*lx)", field_size, field_size,
7572 (unsigned long) proc_flags);
7574 if (unknown_flags)
7576 if (p != buff + field_size + 4)
7578 if (size < 2 + 10 + field_size + 1)
7580 warn (_("Internal error: not enough buffer room for section flag info"));
7581 return _("<unknown>");
7583 size -= 2;
7584 *p++ = ',';
7585 *p++ = ' ';
7587 size -= 10 + field_size;
7588 p += sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
7589 (unsigned long) unknown_flags);
7593 *p = '\0';
7594 return buff;
7597 static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
7598 get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf,
7599 uint64_t size)
7601 if (is_32bit_elf)
7603 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
7605 if (size < sizeof (* echdr))
7607 error (_("Compressed section is too small even for a compression header\n"));
7608 return 0;
7611 chdr->ch_type = BYTE_GET (echdr->ch_type);
7612 chdr->ch_size = BYTE_GET (echdr->ch_size);
7613 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7614 return sizeof (*echdr);
7616 else
7618 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
7620 if (size < sizeof (* echdr))
7622 error (_("Compressed section is too small even for a compression header\n"));
7623 return 0;
7626 chdr->ch_type = BYTE_GET (echdr->ch_type);
7627 chdr->ch_size = BYTE_GET (echdr->ch_size);
7628 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7629 return sizeof (*echdr);
7633 static bool
7634 process_section_headers (Filedata * filedata)
7636 Elf_Internal_Shdr * section;
7637 unsigned int i;
7639 if (filedata->file_header.e_shnum == 0)
7641 /* PR binutils/12467. */
7642 if (filedata->file_header.e_shoff != 0)
7644 warn (_("possibly corrupt ELF file header - it has a non-zero"
7645 " section header offset, but no section headers\n"));
7646 return false;
7648 else if (do_sections)
7649 printf (_("\nThere are no sections in this file.\n"));
7651 return true;
7654 if (do_sections && !do_header)
7656 if (filedata->is_separate && process_links)
7657 printf (_("In linked file '%s': "), filedata->file_name);
7658 if (! filedata->is_separate || process_links)
7659 printf (ngettext ("There is %d section header, "
7660 "starting at offset %#" PRIx64 ":\n",
7661 "There are %d section headers, "
7662 "starting at offset %#" PRIx64 ":\n",
7663 filedata->file_header.e_shnum),
7664 filedata->file_header.e_shnum,
7665 filedata->file_header.e_shoff);
7668 if (!get_section_headers (filedata, false))
7669 return false;
7671 /* Read in the string table, so that we have names to display. */
7672 if (filedata->file_header.e_shstrndx != SHN_UNDEF
7673 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
7675 section = filedata->section_headers + filedata->file_header.e_shstrndx;
7677 if (section->sh_size != 0)
7679 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
7680 1, section->sh_size,
7681 _("string table"));
7683 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
7687 /* Scan the sections for the dynamic symbol table
7688 and dynamic string table and debug sections. */
7689 eh_addr_size = is_32bit_elf ? 4 : 8;
7690 switch (filedata->file_header.e_machine)
7692 case EM_MIPS:
7693 case EM_MIPS_RS3_LE:
7694 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
7695 FDE addresses. However, the ABI also has a semi-official ILP32
7696 variant for which the normal FDE address size rules apply.
7698 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
7699 section, where XX is the size of longs in bits. Unfortunately,
7700 earlier compilers provided no way of distinguishing ILP32 objects
7701 from LP64 objects, so if there's any doubt, we should assume that
7702 the official LP64 form is being used. */
7703 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == EF_MIPS_ABI_EABI64
7704 && find_section (filedata, ".gcc_compiled_long32") == NULL)
7705 eh_addr_size = 8;
7706 break;
7708 case EM_H8_300:
7709 case EM_H8_300H:
7710 switch (filedata->file_header.e_flags & EF_H8_MACH)
7712 case E_H8_MACH_H8300:
7713 case E_H8_MACH_H8300HN:
7714 case E_H8_MACH_H8300SN:
7715 case E_H8_MACH_H8300SXN:
7716 eh_addr_size = 2;
7717 break;
7718 case E_H8_MACH_H8300H:
7719 case E_H8_MACH_H8300S:
7720 case E_H8_MACH_H8300SX:
7721 eh_addr_size = 4;
7722 break;
7724 break;
7726 case EM_M32C_OLD:
7727 case EM_M32C:
7728 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
7730 case EF_M32C_CPU_M16C:
7731 eh_addr_size = 2;
7732 break;
7734 break;
7737 #define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7738 do \
7740 uint64_t expected_entsize = is_32bit_elf ? size32 : size64; \
7741 if (section->sh_entsize != expected_entsize) \
7743 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
7744 i, section->sh_entsize); \
7745 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
7746 expected_entsize); \
7747 section->sh_entsize = expected_entsize; \
7750 while (0)
7752 #define CHECK_ENTSIZE(section, i, type) \
7753 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
7754 sizeof (Elf64_External_##type))
7756 for (i = 0, section = filedata->section_headers;
7757 i < filedata->file_header.e_shnum;
7758 i++, section++)
7760 const char *name = printable_section_name (filedata, section);
7762 /* Run some sanity checks on the headers and
7763 possibly fill in some file data as well. */
7764 switch (section->sh_type)
7766 case SHT_DYNSYM:
7767 if (filedata->dynamic_symbols != NULL)
7769 error (_("File contains multiple dynamic symbol tables\n"));
7770 continue;
7773 CHECK_ENTSIZE (section, i, Sym);
7774 filedata->dynamic_symbols
7775 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
7776 filedata->dynamic_symtab_section = section;
7777 break;
7779 case SHT_STRTAB:
7780 if (streq (name, ".dynstr"))
7782 if (filedata->dynamic_strings != NULL)
7784 error (_("File contains multiple dynamic string tables\n"));
7785 continue;
7788 filedata->dynamic_strings
7789 = (char *) get_data (NULL, filedata, section->sh_offset,
7790 1, section->sh_size, _("dynamic strings"));
7791 filedata->dynamic_strings_length
7792 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
7793 filedata->dynamic_strtab_section = section;
7795 break;
7797 case SHT_SYMTAB_SHNDX:
7799 elf_section_list * entry = xmalloc (sizeof * entry);
7801 entry->hdr = section;
7802 entry->next = filedata->symtab_shndx_list;
7803 filedata->symtab_shndx_list = entry;
7805 break;
7807 case SHT_SYMTAB:
7808 CHECK_ENTSIZE (section, i, Sym);
7809 break;
7811 case SHT_GROUP:
7812 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7813 break;
7815 case SHT_REL:
7816 CHECK_ENTSIZE (section, i, Rel);
7817 if (do_checks && section->sh_size == 0)
7818 warn (_("Section '%s': zero-sized relocation section\n"), name);
7819 break;
7821 case SHT_RELA:
7822 CHECK_ENTSIZE (section, i, Rela);
7823 if (do_checks && section->sh_size == 0)
7824 warn (_("Section '%s': zero-sized relocation section\n"), name);
7825 break;
7827 case SHT_RELR:
7828 CHECK_ENTSIZE (section, i, Relr);
7829 break;
7831 case SHT_NOTE:
7832 case SHT_PROGBITS:
7833 /* Having a zero sized section is not illegal according to the
7834 ELF standard, but it might be an indication that something
7835 is wrong. So issue a warning if we are running in lint mode. */
7836 if (do_checks && section->sh_size == 0)
7837 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7838 break;
7840 default:
7841 break;
7844 if ((do_debugging || do_debug_info || do_debug_abbrevs
7845 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7846 || do_debug_aranges || do_debug_frames || do_debug_macinfo
7847 || do_debug_str || do_debug_str_offsets || do_debug_loc
7848 || do_debug_ranges
7849 || do_debug_addr || do_debug_cu_index || do_debug_links)
7850 && (startswith (name, ".debug_")
7851 || startswith (name, ".zdebug_")))
7853 if (name[1] == 'z')
7854 name += sizeof (".zdebug_") - 1;
7855 else
7856 name += sizeof (".debug_") - 1;
7858 if (do_debugging
7859 || (do_debug_info && startswith (name, "info"))
7860 || (do_debug_info && startswith (name, "types"))
7861 || (do_debug_abbrevs && startswith (name, "abbrev"))
7862 || (do_debug_lines && strcmp (name, "line") == 0)
7863 || (do_debug_lines && startswith (name, "line."))
7864 || (do_debug_pubnames && startswith (name, "pubnames"))
7865 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7866 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7867 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7868 || (do_debug_aranges && startswith (name, "aranges"))
7869 || (do_debug_ranges && startswith (name, "ranges"))
7870 || (do_debug_ranges && startswith (name, "rnglists"))
7871 || (do_debug_frames && startswith (name, "frame"))
7872 || (do_debug_macinfo && startswith (name, "macinfo"))
7873 || (do_debug_macinfo && startswith (name, "macro"))
7874 || (do_debug_str && startswith (name, "str"))
7875 || (do_debug_links && startswith (name, "sup"))
7876 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7877 || (do_debug_loc && startswith (name, "loc"))
7878 || (do_debug_loc && startswith (name, "loclists"))
7879 || (do_debug_addr && startswith (name, "addr"))
7880 || (do_debug_cu_index && startswith (name, "cu_index"))
7881 || (do_debug_cu_index && startswith (name, "tu_index"))
7883 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
7885 /* Linkonce section to be combined with .debug_info at link time. */
7886 else if ((do_debugging || do_debug_info)
7887 && startswith (name, ".gnu.linkonce.wi."))
7888 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
7889 else if (do_debug_frames && streq (name, ".eh_frame"))
7890 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
7891 else if (do_debug_frames && streq (name, ".eh_frame_hdr"))
7892 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
7893 else if (do_gdb_index && (streq (name, ".gdb_index")
7894 || streq (name, ".debug_names")))
7895 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
7896 /* Trace sections for Itanium VMS. */
7897 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7898 || do_trace_aranges)
7899 && startswith (name, ".trace_"))
7901 name += sizeof (".trace_") - 1;
7903 if (do_debugging
7904 || (do_trace_info && streq (name, "info"))
7905 || (do_trace_abbrevs && streq (name, "abbrev"))
7906 || (do_trace_aranges && streq (name, "aranges"))
7908 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
7910 else if ((do_debugging || do_debug_links)
7911 && (startswith (name, ".gnu_debuglink")
7912 || startswith (name, ".gnu_debugaltlink")))
7913 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
7916 if (! do_sections)
7917 return true;
7919 if (filedata->is_separate && ! process_links)
7920 return true;
7922 if (filedata->is_separate)
7923 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7924 else if (filedata->file_header.e_shnum > 1)
7925 printf (_("\nSection Headers:\n"));
7926 else
7927 printf (_("\nSection Header:\n"));
7929 if (is_32bit_elf)
7931 if (do_section_details)
7933 printf (_(" [Nr] Name\n"));
7934 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
7936 else
7937 printf
7938 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7940 else if (do_wide)
7942 if (do_section_details)
7944 printf (_(" [Nr] Name\n"));
7945 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
7947 else
7948 printf
7949 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7951 else
7953 if (do_section_details)
7955 printf (_(" [Nr] Name\n"));
7956 printf (_(" Type Address Offset Link\n"));
7957 printf (_(" Size EntSize Info Align\n"));
7959 else
7961 printf (_(" [Nr] Name Type Address Offset\n"));
7962 printf (_(" Size EntSize Flags Link Info Align\n"));
7966 if (do_section_details)
7967 printf (_(" Flags\n"));
7969 for (i = 0, section = filedata->section_headers;
7970 i < filedata->file_header.e_shnum;
7971 i++, section++)
7973 /* Run some sanity checks on the section header. */
7975 /* Check the sh_link field. */
7976 switch (section->sh_type)
7978 case SHT_REL:
7979 case SHT_RELA:
7980 if (section->sh_link == 0
7981 && (filedata->file_header.e_type == ET_EXEC
7982 || filedata->file_header.e_type == ET_DYN))
7983 /* A dynamic relocation section where all entries use a
7984 zero symbol index need not specify a symtab section. */
7985 break;
7986 /* Fall through. */
7987 case SHT_SYMTAB_SHNDX:
7988 case SHT_GROUP:
7989 case SHT_HASH:
7990 case SHT_GNU_HASH:
7991 case SHT_GNU_versym:
7992 if (section->sh_link == 0
7993 || section->sh_link >= filedata->file_header.e_shnum
7994 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7995 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
7996 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7997 i, section->sh_link);
7998 break;
8000 case SHT_DYNAMIC:
8001 case SHT_SYMTAB:
8002 case SHT_DYNSYM:
8003 case SHT_GNU_verneed:
8004 case SHT_GNU_verdef:
8005 case SHT_GNU_LIBLIST:
8006 if (section->sh_link == 0
8007 || section->sh_link >= filedata->file_header.e_shnum
8008 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
8009 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
8010 i, section->sh_link);
8011 break;
8013 case SHT_INIT_ARRAY:
8014 case SHT_FINI_ARRAY:
8015 case SHT_PREINIT_ARRAY:
8016 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
8017 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
8018 i, section->sh_link);
8019 break;
8021 default:
8022 /* FIXME: Add support for target specific section types. */
8023 #if 0 /* Currently we do not check other section types as there are too
8024 many special cases. Stab sections for example have a type
8025 of SHT_PROGBITS but an sh_link field that links to the .stabstr
8026 section. */
8027 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
8028 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
8029 i, section->sh_link);
8030 #endif
8031 break;
8034 /* Check the sh_info field. */
8035 switch (section->sh_type)
8037 case SHT_REL:
8038 case SHT_RELA:
8039 if (section->sh_info == 0
8040 && (filedata->file_header.e_type == ET_EXEC
8041 || filedata->file_header.e_type == ET_DYN))
8042 /* Dynamic relocations apply to segments, so they do not
8043 need to specify the section they relocate. */
8044 break;
8045 if (section->sh_info == 0
8046 || section->sh_info >= filedata->file_header.e_shnum
8047 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
8048 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
8049 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
8050 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
8051 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
8052 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
8053 /* FIXME: Are other section types valid ? */
8054 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
8055 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
8056 i, section->sh_info);
8057 break;
8059 case SHT_DYNAMIC:
8060 case SHT_HASH:
8061 case SHT_SYMTAB_SHNDX:
8062 case SHT_INIT_ARRAY:
8063 case SHT_FINI_ARRAY:
8064 case SHT_PREINIT_ARRAY:
8065 if (section->sh_info != 0)
8066 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
8067 i, section->sh_info);
8068 break;
8070 case SHT_GROUP:
8071 case SHT_SYMTAB:
8072 case SHT_DYNSYM:
8073 /* A symbol index - we assume that it is valid. */
8074 break;
8076 default:
8077 /* FIXME: Add support for target specific section types. */
8078 if (section->sh_type == SHT_NOBITS)
8079 /* NOBITS section headers with non-zero sh_info fields can be
8080 created when a binary is stripped of everything but its debug
8081 information. The stripped sections have their headers
8082 preserved but their types set to SHT_NOBITS. So do not check
8083 this type of section. */
8085 else if (section->sh_flags & SHF_INFO_LINK)
8087 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
8088 warn (_("[%2u]: Expected link to another section in info field"), i);
8090 else if (section->sh_type < SHT_LOOS
8091 && (section->sh_flags & SHF_GNU_MBIND) == 0
8092 && section->sh_info != 0)
8093 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
8094 i, section->sh_info);
8095 break;
8098 /* Check the sh_size field. */
8099 if (section->sh_size > filedata->file_size
8100 && section->sh_type != SHT_NOBITS
8101 && section->sh_type != SHT_NULL
8102 && section->sh_type < SHT_LOOS)
8103 warn (_("Size of section %u is larger than the entire file!\n"), i);
8105 printf (" [%2u] ", i);
8106 if (do_section_details)
8107 printf ("%s\n ", printable_section_name (filedata, section));
8108 else
8109 print_symbol_name (-17, printable_section_name (filedata, section));
8111 printf (do_wide ? " %-15s " : " %-15.15s ",
8112 get_section_type_name (filedata, section->sh_type));
8114 if (is_32bit_elf)
8116 const char * link_too_big = NULL;
8118 print_vma (section->sh_addr, LONG_HEX);
8120 printf ( " %6.6lx %6.6lx %2.2lx",
8121 (unsigned long) section->sh_offset,
8122 (unsigned long) section->sh_size,
8123 (unsigned long) section->sh_entsize);
8125 if (do_section_details)
8126 fputs (" ", stdout);
8127 else
8128 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
8130 if (section->sh_link >= filedata->file_header.e_shnum)
8132 link_too_big = "";
8133 /* The sh_link value is out of range. Normally this indicates
8134 an error but it can have special values in Solaris binaries. */
8135 switch (filedata->file_header.e_machine)
8137 case EM_386:
8138 case EM_IAMCU:
8139 case EM_X86_64:
8140 case EM_L1OM:
8141 case EM_K1OM:
8142 case EM_OLD_SPARCV9:
8143 case EM_SPARC32PLUS:
8144 case EM_SPARCV9:
8145 case EM_SPARC:
8146 if (section->sh_link == (SHN_BEFORE & 0xffff))
8147 link_too_big = "BEFORE";
8148 else if (section->sh_link == (SHN_AFTER & 0xffff))
8149 link_too_big = "AFTER";
8150 break;
8151 default:
8152 break;
8156 if (do_section_details)
8158 if (link_too_big != NULL && * link_too_big)
8159 printf ("<%s> ", link_too_big);
8160 else
8161 printf ("%2u ", section->sh_link);
8162 printf ("%3u %2lu\n", section->sh_info,
8163 (unsigned long) section->sh_addralign);
8165 else
8166 printf ("%2u %3u %2lu\n",
8167 section->sh_link,
8168 section->sh_info,
8169 (unsigned long) section->sh_addralign);
8171 if (link_too_big && ! * link_too_big)
8172 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
8173 i, section->sh_link);
8175 else if (do_wide)
8177 print_vma (section->sh_addr, LONG_HEX);
8179 if ((long) section->sh_offset == section->sh_offset)
8180 printf (" %6.6lx", (unsigned long) section->sh_offset);
8181 else
8183 putchar (' ');
8184 print_vma (section->sh_offset, LONG_HEX);
8187 if ((unsigned long) section->sh_size == section->sh_size)
8188 printf (" %6.6lx", (unsigned long) section->sh_size);
8189 else
8191 putchar (' ');
8192 print_vma (section->sh_size, LONG_HEX);
8195 if ((unsigned long) section->sh_entsize == section->sh_entsize)
8196 printf (" %2.2lx", (unsigned long) section->sh_entsize);
8197 else
8199 putchar (' ');
8200 print_vma (section->sh_entsize, LONG_HEX);
8203 if (do_section_details)
8204 fputs (" ", stdout);
8205 else
8206 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
8208 printf ("%2u %3u ", section->sh_link, section->sh_info);
8210 if ((unsigned long) section->sh_addralign == section->sh_addralign)
8211 printf ("%2lu\n", (unsigned long) section->sh_addralign);
8212 else
8214 print_vma (section->sh_addralign, DEC);
8215 putchar ('\n');
8218 else if (do_section_details)
8220 putchar (' ');
8221 print_vma (section->sh_addr, LONG_HEX);
8222 if ((long) section->sh_offset == section->sh_offset)
8223 printf (" %16.16lx", (unsigned long) section->sh_offset);
8224 else
8226 printf (" ");
8227 print_vma (section->sh_offset, LONG_HEX);
8229 printf (" %u\n ", section->sh_link);
8230 print_vma (section->sh_size, LONG_HEX);
8231 putchar (' ');
8232 print_vma (section->sh_entsize, LONG_HEX);
8234 printf (" %-16u %lu\n",
8235 section->sh_info,
8236 (unsigned long) section->sh_addralign);
8238 else
8240 putchar (' ');
8241 print_vma (section->sh_addr, LONG_HEX);
8242 if ((long) section->sh_offset == section->sh_offset)
8243 printf (" %8.8lx", (unsigned long) section->sh_offset);
8244 else
8246 printf (" ");
8247 print_vma (section->sh_offset, LONG_HEX);
8249 printf ("\n ");
8250 print_vma (section->sh_size, LONG_HEX);
8251 printf (" ");
8252 print_vma (section->sh_entsize, LONG_HEX);
8254 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
8256 printf (" %2u %3u %lu\n",
8257 section->sh_link,
8258 section->sh_info,
8259 (unsigned long) section->sh_addralign);
8262 if (do_section_details)
8264 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
8265 if ((section->sh_flags & SHF_COMPRESSED) != 0)
8267 /* Minimum section size is 12 bytes for 32-bit compression
8268 header + 12 bytes for compressed data header. */
8269 unsigned char buf[24];
8271 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
8272 if (get_data (&buf, filedata, section->sh_offset, 1,
8273 sizeof (buf), _("compression header")))
8275 Elf_Internal_Chdr chdr;
8277 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
8278 printf (_(" [<corrupt>]\n"));
8279 else
8281 if (chdr.ch_type == ch_compress_zlib)
8282 printf (" ZLIB, ");
8283 else if (chdr.ch_type == ch_compress_zstd)
8284 printf (" ZSTD, ");
8285 else
8286 printf (_(" [<unknown>: 0x%x], "),
8287 chdr.ch_type);
8288 print_vma (chdr.ch_size, LONG_HEX);
8289 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
8296 if (!do_section_details)
8298 /* The ordering of the letters shown here matches the ordering of the
8299 corresponding SHF_xxx values, and hence the order in which these
8300 letters will be displayed to the user. */
8301 printf (_("Key to Flags:\n\
8302 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
8303 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
8304 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
8305 switch (filedata->file_header.e_ident[EI_OSABI])
8307 case ELFOSABI_GNU:
8308 case ELFOSABI_FREEBSD:
8309 printf (_("R (retain), "));
8310 /* Fall through */
8311 case ELFOSABI_NONE:
8312 printf (_("D (mbind), "));
8313 break;
8314 default:
8315 break;
8317 if (filedata->file_header.e_machine == EM_X86_64
8318 || filedata->file_header.e_machine == EM_L1OM
8319 || filedata->file_header.e_machine == EM_K1OM)
8320 printf (_("l (large), "));
8321 else if (filedata->file_header.e_machine == EM_ARM)
8322 printf (_("y (purecode), "));
8323 else if (filedata->file_header.e_machine == EM_PPC)
8324 printf (_("v (VLE), "));
8325 printf ("p (processor specific)\n");
8328 return true;
8331 static bool
8332 get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
8333 Elf_Internal_Sym **symtab, uint64_t *nsyms,
8334 char **strtab, uint64_t *strtablen)
8336 *strtab = NULL;
8337 *strtablen = 0;
8338 *symtab = get_elf_symbols (filedata, symsec, nsyms);
8340 if (*symtab == NULL)
8341 return false;
8343 if (symsec->sh_link != 0)
8345 Elf_Internal_Shdr *strsec;
8347 if (symsec->sh_link >= filedata->file_header.e_shnum)
8349 error (_("Bad sh_link in symbol table section\n"));
8350 free (*symtab);
8351 *symtab = NULL;
8352 *nsyms = 0;
8353 return false;
8356 strsec = filedata->section_headers + symsec->sh_link;
8358 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
8359 1, strsec->sh_size, _("string table"));
8360 if (*strtab == NULL)
8362 free (*symtab);
8363 *symtab = NULL;
8364 *nsyms = 0;
8365 return false;
8367 *strtablen = strsec->sh_size;
8369 return true;
8372 static const char *
8373 get_group_flags (unsigned int flags)
8375 static char buff[128];
8377 if (flags == 0)
8378 return "";
8379 else if (flags == GRP_COMDAT)
8380 return "COMDAT ";
8382 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
8383 flags,
8384 flags & GRP_MASKOS ? _("<OS specific>") : "",
8385 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
8386 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
8387 ? _("<unknown>") : ""));
8389 return buff;
8392 static bool
8393 process_section_groups (Filedata * filedata)
8395 Elf_Internal_Shdr * section;
8396 unsigned int i;
8397 struct group * group;
8398 Elf_Internal_Shdr * symtab_sec;
8399 Elf_Internal_Shdr * strtab_sec;
8400 Elf_Internal_Sym * symtab;
8401 uint64_t num_syms;
8402 char * strtab;
8403 size_t strtab_size;
8405 /* Don't process section groups unless needed. */
8406 if (!do_unwind && !do_section_groups)
8407 return true;
8409 if (filedata->file_header.e_shnum == 0)
8411 if (do_section_groups)
8413 if (filedata->is_separate)
8414 printf (_("\nThere are no sections group in linked file '%s'.\n"),
8415 filedata->file_name);
8416 else
8417 printf (_("\nThere are no section groups in this file.\n"));
8419 return true;
8422 if (filedata->section_headers == NULL)
8424 error (_("Section headers are not available!\n"));
8425 /* PR 13622: This can happen with a corrupt ELF header. */
8426 return false;
8429 filedata->section_headers_groups
8430 = (struct group **) calloc (filedata->file_header.e_shnum,
8431 sizeof (struct group *));
8433 if (filedata->section_headers_groups == NULL)
8435 error (_("Out of memory reading %u section group headers\n"),
8436 filedata->file_header.e_shnum);
8437 return false;
8440 /* Scan the sections for the group section. */
8441 filedata->group_count = 0;
8442 for (i = 0, section = filedata->section_headers;
8443 i < filedata->file_header.e_shnum;
8444 i++, section++)
8445 if (section->sh_type == SHT_GROUP)
8446 filedata->group_count++;
8448 if (filedata->group_count == 0)
8450 if (do_section_groups)
8452 if (filedata->is_separate)
8453 printf (_("\nThere are no section groups in linked file '%s'.\n"),
8454 filedata->file_name);
8455 else
8456 printf (_("\nThere are no section groups in this file.\n"));
8459 return true;
8462 filedata->section_groups = (struct group *) calloc (filedata->group_count,
8463 sizeof (struct group));
8465 if (filedata->section_groups == NULL)
8467 error (_("Out of memory reading %zu groups\n"), filedata->group_count);
8468 return false;
8471 symtab_sec = NULL;
8472 strtab_sec = NULL;
8473 symtab = NULL;
8474 num_syms = 0;
8475 strtab = NULL;
8476 strtab_size = 0;
8478 if (filedata->is_separate)
8479 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
8481 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
8482 i < filedata->file_header.e_shnum;
8483 i++, section++)
8485 if (section->sh_type == SHT_GROUP)
8487 const char * name = printable_section_name (filedata, section);
8488 const char * group_name;
8489 unsigned char * start;
8490 unsigned char * indices;
8491 unsigned int entry, j, size;
8492 Elf_Internal_Shdr * sec;
8493 Elf_Internal_Sym * sym;
8495 /* Get the symbol table. */
8496 if (section->sh_link >= filedata->file_header.e_shnum
8497 || ((sec = filedata->section_headers + section->sh_link)->sh_type
8498 != SHT_SYMTAB))
8500 error (_("Bad sh_link in group section `%s'\n"), name);
8501 continue;
8504 if (symtab_sec != sec)
8506 symtab_sec = sec;
8507 free (symtab);
8508 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
8511 if (symtab == NULL)
8513 error (_("Corrupt header in group section `%s'\n"), name);
8514 continue;
8517 if (section->sh_info >= num_syms)
8519 error (_("Bad sh_info in group section `%s'\n"), name);
8520 continue;
8523 sym = symtab + section->sh_info;
8525 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
8527 if (sym->st_shndx == 0
8528 || sym->st_shndx >= filedata->file_header.e_shnum)
8530 error (_("Bad sh_info in group section `%s'\n"), name);
8531 continue;
8534 group_name = printable_section_name (filedata,
8535 filedata->section_headers
8536 + sym->st_shndx);
8537 strtab_sec = NULL;
8538 free (strtab);
8539 strtab = NULL;
8540 strtab_size = 0;
8542 else
8544 /* Get the string table. */
8545 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
8547 strtab_sec = NULL;
8548 free (strtab);
8549 strtab = NULL;
8550 strtab_size = 0;
8552 else if (strtab_sec
8553 != (sec = filedata->section_headers + symtab_sec->sh_link))
8555 strtab_sec = sec;
8556 free (strtab);
8558 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
8559 1, strtab_sec->sh_size,
8560 _("string table"));
8561 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
8563 group_name = sym->st_name < strtab_size
8564 ? strtab + sym->st_name : _("<corrupt>");
8567 /* PR 17531: file: loop. */
8568 if (section->sh_entsize > section->sh_size)
8570 error (_("Section %s has sh_entsize (%#" PRIx64 ")"
8571 " which is larger than its size (%#" PRIx64 ")\n"),
8572 printable_section_name (filedata, section),
8573 section->sh_entsize,
8574 section->sh_size);
8575 continue;
8578 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
8579 1, section->sh_size,
8580 _("section data"));
8581 if (start == NULL)
8582 continue;
8584 indices = start;
8585 size = (section->sh_size / section->sh_entsize) - 1;
8586 entry = byte_get (indices, 4);
8587 indices += 4;
8589 if (do_section_groups)
8591 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
8592 get_group_flags (entry), i, name, group_name, size);
8594 printf (_(" [Index] Name\n"));
8597 group->group_index = i;
8599 for (j = 0; j < size; j++)
8601 struct group_list * g;
8603 entry = byte_get (indices, 4);
8604 indices += 4;
8606 if (entry >= filedata->file_header.e_shnum)
8608 static unsigned num_group_errors = 0;
8610 if (num_group_errors ++ < 10)
8612 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
8613 entry, i, filedata->file_header.e_shnum - 1);
8614 if (num_group_errors == 10)
8615 warn (_("Further error messages about overlarge group section indices suppressed\n"));
8617 continue;
8620 if (filedata->section_headers_groups [entry] != NULL)
8622 if (entry)
8624 static unsigned num_errs = 0;
8626 if (num_errs ++ < 10)
8628 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
8629 entry, i,
8630 filedata->section_headers_groups [entry]->group_index);
8631 if (num_errs == 10)
8632 warn (_("Further error messages about already contained group sections suppressed\n"));
8634 continue;
8636 else
8638 /* Intel C/C++ compiler may put section 0 in a
8639 section group. We just warn it the first time
8640 and ignore it afterwards. */
8641 static bool warned = false;
8642 if (!warned)
8644 error (_("section 0 in group section [%5u]\n"),
8645 filedata->section_headers_groups [entry]->group_index);
8646 warned = true;
8651 filedata->section_headers_groups [entry] = group;
8653 if (do_section_groups)
8655 sec = filedata->section_headers + entry;
8656 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
8659 g = (struct group_list *) xmalloc (sizeof (struct group_list));
8660 g->section_index = entry;
8661 g->next = group->root;
8662 group->root = g;
8665 free (start);
8667 group++;
8671 free (symtab);
8672 free (strtab);
8673 return true;
8676 /* Data used to display dynamic fixups. */
8678 struct ia64_vms_dynfixup
8680 uint64_t needed_ident; /* Library ident number. */
8681 uint64_t needed; /* Index in the dstrtab of the library name. */
8682 uint64_t fixup_needed; /* Index of the library. */
8683 uint64_t fixup_rela_cnt; /* Number of fixups. */
8684 uint64_t fixup_rela_off; /* Fixups offset in the dynamic segment. */
8687 /* Data used to display dynamic relocations. */
8689 struct ia64_vms_dynimgrela
8691 uint64_t img_rela_cnt; /* Number of relocations. */
8692 uint64_t img_rela_off; /* Reloc offset in the dynamic segment. */
8695 /* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
8696 library). */
8698 static bool
8699 dump_ia64_vms_dynamic_fixups (Filedata * filedata,
8700 struct ia64_vms_dynfixup * fixup,
8701 const char * strtab,
8702 unsigned int strtab_sz)
8704 Elf64_External_VMS_IMAGE_FIXUP * imfs;
8705 size_t i;
8706 const char * lib_name;
8708 imfs = get_data (NULL, filedata,
8709 filedata->dynamic_addr + fixup->fixup_rela_off,
8710 sizeof (*imfs), fixup->fixup_rela_cnt,
8711 _("dynamic section image fixups"));
8712 if (!imfs)
8713 return false;
8715 if (fixup->needed < strtab_sz)
8716 lib_name = strtab + fixup->needed;
8717 else
8719 warn (_("corrupt library name index of %#" PRIx64
8720 " found in dynamic entry"), fixup->needed);
8721 lib_name = "???";
8724 printf (_("\nImage fixups for needed library #%" PRId64
8725 ": %s - ident: %" PRIx64 "\n"),
8726 fixup->fixup_needed, lib_name, fixup->needed_ident);
8727 printf
8728 (_("Seg Offset Type SymVec DataType\n"));
8730 for (i = 0; i < (size_t) fixup->fixup_rela_cnt; i++)
8732 unsigned int type;
8733 const char *rtype;
8735 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
8736 printf ("%016" PRIx64 " ", BYTE_GET (imfs [i].fixup_offset));
8737 type = BYTE_GET (imfs [i].type);
8738 rtype = elf_ia64_reloc_type (type);
8739 if (rtype == NULL)
8740 printf ("0x%08x ", type);
8741 else
8742 printf ("%-32s ", rtype);
8743 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8744 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8747 free (imfs);
8748 return true;
8751 /* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8753 static bool
8754 dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
8756 Elf64_External_VMS_IMAGE_RELA *imrs;
8757 size_t i;
8759 imrs = get_data (NULL, filedata,
8760 filedata->dynamic_addr + imgrela->img_rela_off,
8761 sizeof (*imrs), imgrela->img_rela_cnt,
8762 _("dynamic section image relocations"));
8763 if (!imrs)
8764 return false;
8766 printf (_("\nImage relocs\n"));
8767 printf
8768 (_("Seg Offset Type Addend Seg Sym Off\n"));
8770 for (i = 0; i < (size_t) imgrela->img_rela_cnt; i++)
8772 unsigned int type;
8773 const char *rtype;
8775 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
8776 printf ("%08" PRIx64 " ", BYTE_GET (imrs [i].rela_offset));
8777 type = BYTE_GET (imrs [i].type);
8778 rtype = elf_ia64_reloc_type (type);
8779 if (rtype == NULL)
8780 printf ("0x%08x ", type);
8781 else
8782 printf ("%-31s ", rtype);
8783 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8784 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
8785 printf ("%08" PRIx64 "\n", BYTE_GET (imrs [i].sym_offset));
8788 free (imrs);
8789 return true;
8792 /* Display IA-64 OpenVMS dynamic relocations and fixups. */
8794 static bool
8795 process_ia64_vms_dynamic_relocs (Filedata * filedata)
8797 struct ia64_vms_dynfixup fixup;
8798 struct ia64_vms_dynimgrela imgrela;
8799 Elf_Internal_Dyn *entry;
8800 uint64_t strtab_off = 0;
8801 uint64_t strtab_sz = 0;
8802 char *strtab = NULL;
8803 bool res = true;
8805 memset (&fixup, 0, sizeof (fixup));
8806 memset (&imgrela, 0, sizeof (imgrela));
8808 /* Note: the order of the entries is specified by the OpenVMS specs. */
8809 for (entry = filedata->dynamic_section;
8810 entry < filedata->dynamic_section + filedata->dynamic_nent;
8811 entry++)
8813 switch (entry->d_tag)
8815 case DT_IA_64_VMS_STRTAB_OFFSET:
8816 strtab_off = entry->d_un.d_val;
8817 break;
8818 case DT_STRSZ:
8819 strtab_sz = entry->d_un.d_val;
8820 if (strtab == NULL)
8821 strtab = get_data (NULL, filedata,
8822 filedata->dynamic_addr + strtab_off,
8823 1, strtab_sz, _("dynamic string section"));
8824 if (strtab == NULL)
8825 strtab_sz = 0;
8826 break;
8828 case DT_IA_64_VMS_NEEDED_IDENT:
8829 fixup.needed_ident = entry->d_un.d_val;
8830 break;
8831 case DT_NEEDED:
8832 fixup.needed = entry->d_un.d_val;
8833 break;
8834 case DT_IA_64_VMS_FIXUP_NEEDED:
8835 fixup.fixup_needed = entry->d_un.d_val;
8836 break;
8837 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8838 fixup.fixup_rela_cnt = entry->d_un.d_val;
8839 break;
8840 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8841 fixup.fixup_rela_off = entry->d_un.d_val;
8842 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
8843 res = false;
8844 break;
8845 case DT_IA_64_VMS_IMG_RELA_CNT:
8846 imgrela.img_rela_cnt = entry->d_un.d_val;
8847 break;
8848 case DT_IA_64_VMS_IMG_RELA_OFF:
8849 imgrela.img_rela_off = entry->d_un.d_val;
8850 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
8851 res = false;
8852 break;
8854 default:
8855 break;
8859 free (strtab);
8861 return res;
8864 static struct
8866 const char * name;
8867 int reloc;
8868 int size;
8869 relocation_type rel_type;
8871 dynamic_relocations [] =
8873 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8874 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8875 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8876 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
8879 /* Process the reloc section. */
8881 static bool
8882 process_relocs (Filedata * filedata)
8884 uint64_t rel_size;
8885 uint64_t rel_offset;
8887 if (!do_reloc)
8888 return true;
8890 if (do_using_dynamic)
8892 relocation_type rel_type;
8893 const char * name;
8894 bool has_dynamic_reloc;
8895 unsigned int i;
8897 has_dynamic_reloc = false;
8899 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
8901 rel_type = dynamic_relocations [i].rel_type;
8902 name = dynamic_relocations [i].name;
8903 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8904 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
8906 if (rel_size)
8907 has_dynamic_reloc = true;
8909 if (rel_type == reltype_unknown)
8911 if (dynamic_relocations [i].reloc == DT_JMPREL)
8912 switch (filedata->dynamic_info[DT_PLTREL])
8914 case DT_REL:
8915 rel_type = reltype_rel;
8916 break;
8917 case DT_RELA:
8918 rel_type = reltype_rela;
8919 break;
8923 if (rel_size)
8925 if (filedata->is_separate)
8926 printf
8927 (_("\nIn linked file '%s' section '%s' at offset %#" PRIx64
8928 " contains %" PRId64 " bytes:\n"),
8929 filedata->file_name, name, rel_offset, rel_size);
8930 else
8931 printf
8932 (_("\n'%s' relocation section at offset %#" PRIx64
8933 " contains %" PRId64 " bytes:\n"),
8934 name, rel_offset, rel_size);
8936 dump_relocations (filedata,
8937 offset_from_vma (filedata, rel_offset, rel_size),
8938 rel_size,
8939 filedata->dynamic_symbols,
8940 filedata->num_dynamic_syms,
8941 filedata->dynamic_strings,
8942 filedata->dynamic_strings_length,
8943 rel_type, true /* is_dynamic */);
8947 if (is_ia64_vms (filedata))
8948 if (process_ia64_vms_dynamic_relocs (filedata))
8949 has_dynamic_reloc = true;
8951 if (! has_dynamic_reloc)
8953 if (filedata->is_separate)
8954 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8955 filedata->file_name);
8956 else
8957 printf (_("\nThere are no dynamic relocations in this file.\n"));
8960 else
8962 Elf_Internal_Shdr * section;
8963 size_t i;
8964 bool found = false;
8966 for (i = 0, section = filedata->section_headers;
8967 i < filedata->file_header.e_shnum;
8968 i++, section++)
8970 if ( section->sh_type != SHT_RELA
8971 && section->sh_type != SHT_REL
8972 && section->sh_type != SHT_RELR)
8973 continue;
8975 rel_offset = section->sh_offset;
8976 rel_size = section->sh_size;
8978 if (rel_size)
8980 relocation_type rel_type;
8981 uint64_t num_rela;
8983 if (filedata->is_separate)
8984 printf (_("\nIn linked file '%s' relocation section "),
8985 filedata->file_name);
8986 else
8987 printf (_("\nRelocation section "));
8989 if (filedata->string_table == NULL)
8990 printf ("%d", section->sh_name);
8991 else
8992 printf ("'%s'", printable_section_name (filedata, section));
8994 num_rela = rel_size / section->sh_entsize;
8995 printf (ngettext (" at offset %#" PRIx64
8996 " contains %" PRIu64 " entry:\n",
8997 " at offset %#" PRIx64
8998 " contains %" PRId64 " entries:\n",
8999 num_rela),
9000 rel_offset, num_rela);
9002 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
9003 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
9005 if (section->sh_link != 0
9006 && section->sh_link < filedata->file_header.e_shnum)
9008 Elf_Internal_Shdr *symsec;
9009 Elf_Internal_Sym *symtab;
9010 uint64_t nsyms;
9011 uint64_t strtablen = 0;
9012 char *strtab = NULL;
9014 symsec = filedata->section_headers + section->sh_link;
9015 if (symsec->sh_type != SHT_SYMTAB
9016 && symsec->sh_type != SHT_DYNSYM)
9017 continue;
9019 if (!get_symtab (filedata, symsec,
9020 &symtab, &nsyms, &strtab, &strtablen))
9021 continue;
9023 dump_relocations (filedata, rel_offset, rel_size,
9024 symtab, nsyms, strtab, strtablen,
9025 rel_type,
9026 symsec->sh_type == SHT_DYNSYM);
9027 free (strtab);
9028 free (symtab);
9030 else
9031 dump_relocations (filedata, rel_offset, rel_size,
9032 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
9034 found = true;
9038 if (! found)
9040 /* Users sometimes forget the -D option, so try to be helpful. */
9041 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
9043 if (filedata->dynamic_info[dynamic_relocations [i].size])
9045 if (filedata->is_separate)
9046 printf (_("\nThere are no static relocations in linked file '%s'."),
9047 filedata->file_name);
9048 else
9049 printf (_("\nThere are no static relocations in this file."));
9050 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
9052 break;
9055 if (i == ARRAY_SIZE (dynamic_relocations))
9057 if (filedata->is_separate)
9058 printf (_("\nThere are no relocations in linked file '%s'.\n"),
9059 filedata->file_name);
9060 else
9061 printf (_("\nThere are no relocations in this file.\n"));
9066 return true;
9069 /* An absolute address consists of a section and an offset. If the
9070 section is NULL, the offset itself is the address, otherwise, the
9071 address equals to LOAD_ADDRESS(section) + offset. */
9073 struct absaddr
9075 unsigned short section;
9076 uint64_t offset;
9079 /* Find the nearest symbol at or below ADDR. Returns the symbol
9080 name, if found, and the offset from the symbol to ADDR. */
9082 static void
9083 find_symbol_for_address (Filedata *filedata,
9084 Elf_Internal_Sym *symtab,
9085 uint64_t nsyms,
9086 const char *strtab,
9087 uint64_t strtab_size,
9088 struct absaddr addr,
9089 const char **symname,
9090 uint64_t *offset)
9092 uint64_t dist = 0x100000;
9093 Elf_Internal_Sym * sym;
9094 Elf_Internal_Sym * beg;
9095 Elf_Internal_Sym * end;
9096 Elf_Internal_Sym * best = NULL;
9098 REMOVE_ARCH_BITS (addr.offset);
9099 beg = symtab;
9100 end = symtab + nsyms;
9102 while (beg < end)
9104 uint64_t value;
9106 sym = beg + (end - beg) / 2;
9108 value = sym->st_value;
9109 REMOVE_ARCH_BITS (value);
9111 if (sym->st_name != 0
9112 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
9113 && addr.offset >= value
9114 && addr.offset - value < dist)
9116 best = sym;
9117 dist = addr.offset - value;
9118 if (!dist)
9119 break;
9122 if (addr.offset < value)
9123 end = sym;
9124 else
9125 beg = sym + 1;
9128 if (best)
9130 *symname = (best->st_name >= strtab_size
9131 ? _("<corrupt>") : strtab + best->st_name);
9132 *offset = dist;
9133 return;
9136 *symname = NULL;
9137 *offset = addr.offset;
9140 static /* signed */ int
9141 symcmp (const void *p, const void *q)
9143 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
9144 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
9146 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
9149 /* Process the unwind section. */
9151 #include "unwind-ia64.h"
9153 struct ia64_unw_table_entry
9155 struct absaddr start;
9156 struct absaddr end;
9157 struct absaddr info;
9160 struct ia64_unw_aux_info
9162 struct ia64_unw_table_entry * table; /* Unwind table. */
9163 uint64_t table_len; /* Length of unwind table. */
9164 unsigned char * info; /* Unwind info. */
9165 uint64_t info_size; /* Size of unwind info. */
9166 uint64_t info_addr; /* Starting address of unwind info. */
9167 uint64_t seg_base; /* Starting address of segment. */
9168 Elf_Internal_Sym * symtab; /* The symbol table. */
9169 uint64_t nsyms; /* Number of symbols. */
9170 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9171 uint64_t nfuns; /* Number of entries in funtab. */
9172 char * strtab; /* The string table. */
9173 uint64_t strtab_size; /* Size of string table. */
9176 static bool
9177 dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
9179 struct ia64_unw_table_entry * tp;
9180 size_t j, nfuns;
9181 int in_body;
9182 bool res = true;
9184 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9185 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9186 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9187 aux->funtab[nfuns++] = aux->symtab[j];
9188 aux->nfuns = nfuns;
9189 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9191 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9193 uint64_t stamp;
9194 uint64_t offset;
9195 const unsigned char * dp;
9196 const unsigned char * head;
9197 const unsigned char * end;
9198 const char * procname;
9200 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
9201 aux->strtab_size, tp->start, &procname, &offset);
9203 fputs ("\n<", stdout);
9205 if (procname)
9207 fputs (procname, stdout);
9209 if (offset)
9210 printf ("+%" PRIx64, offset);
9213 fputs (">: [", stdout);
9214 print_vma (tp->start.offset, PREFIX_HEX);
9215 fputc ('-', stdout);
9216 print_vma (tp->end.offset, PREFIX_HEX);
9217 printf ("], info at +0x%" PRIx64 "\n",
9218 tp->info.offset - aux->seg_base);
9220 /* PR 17531: file: 86232b32. */
9221 if (aux->info == NULL)
9222 continue;
9224 offset = tp->info.offset;
9225 if (tp->info.section)
9227 if (tp->info.section >= filedata->file_header.e_shnum)
9229 warn (_("Invalid section %u in table entry %td\n"),
9230 tp->info.section, tp - aux->table);
9231 res = false;
9232 continue;
9234 offset += filedata->section_headers[tp->info.section].sh_addr;
9236 offset -= aux->info_addr;
9237 /* PR 17531: file: 0997b4d1. */
9238 if (offset >= aux->info_size
9239 || aux->info_size - offset < 8)
9241 warn (_("Invalid offset %" PRIx64 " in table entry %td\n"),
9242 tp->info.offset, tp - aux->table);
9243 res = false;
9244 continue;
9247 head = aux->info + offset;
9248 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
9250 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
9251 (unsigned) UNW_VER (stamp),
9252 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
9253 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
9254 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
9255 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
9257 if (UNW_VER (stamp) != 1)
9259 printf (_("\tUnknown version.\n"));
9260 continue;
9263 in_body = 0;
9264 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
9265 /* PR 17531: file: 16ceda89. */
9266 if (end > aux->info + aux->info_size)
9267 end = aux->info + aux->info_size;
9268 for (dp = head + 8; dp < end;)
9269 dp = unw_decode (dp, in_body, & in_body, end);
9272 free (aux->funtab);
9274 return res;
9277 static bool
9278 slurp_ia64_unwind_table (Filedata * filedata,
9279 struct ia64_unw_aux_info * aux,
9280 Elf_Internal_Shdr * sec)
9282 uint64_t size, nrelas, i;
9283 Elf_Internal_Phdr * seg;
9284 struct ia64_unw_table_entry * tep;
9285 Elf_Internal_Shdr * relsec;
9286 Elf_Internal_Rela * rela;
9287 Elf_Internal_Rela * rp;
9288 unsigned char * table;
9289 unsigned char * tp;
9290 Elf_Internal_Sym * sym;
9291 const char * relname;
9293 aux->table_len = 0;
9295 /* First, find the starting address of the segment that includes
9296 this section: */
9298 if (filedata->file_header.e_phnum)
9300 if (! get_program_headers (filedata))
9301 return false;
9303 for (seg = filedata->program_headers;
9304 seg < filedata->program_headers + filedata->file_header.e_phnum;
9305 ++seg)
9307 if (seg->p_type != PT_LOAD)
9308 continue;
9310 if (sec->sh_addr >= seg->p_vaddr
9311 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9313 aux->seg_base = seg->p_vaddr;
9314 break;
9319 /* Second, build the unwind table from the contents of the unwind section: */
9320 size = sec->sh_size;
9321 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
9322 _("unwind table"));
9323 if (!table)
9324 return false;
9326 aux->table_len = size / (3 * eh_addr_size);
9327 aux->table = (struct ia64_unw_table_entry *)
9328 xcmalloc (aux->table_len, sizeof (aux->table[0]));
9329 tep = aux->table;
9331 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
9333 tep->start.section = SHN_UNDEF;
9334 tep->end.section = SHN_UNDEF;
9335 tep->info.section = SHN_UNDEF;
9336 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9337 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9338 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9339 tep->start.offset += aux->seg_base;
9340 tep->end.offset += aux->seg_base;
9341 tep->info.offset += aux->seg_base;
9343 free (table);
9345 /* Third, apply any relocations to the unwind table: */
9346 for (relsec = filedata->section_headers;
9347 relsec < filedata->section_headers + filedata->file_header.e_shnum;
9348 ++relsec)
9350 if (relsec->sh_type != SHT_RELA
9351 || relsec->sh_info >= filedata->file_header.e_shnum
9352 || filedata->section_headers + relsec->sh_info != sec)
9353 continue;
9355 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
9356 & rela, & nrelas))
9358 free (aux->table);
9359 aux->table = NULL;
9360 aux->table_len = 0;
9361 return false;
9364 for (rp = rela; rp < rela + nrelas; ++rp)
9366 unsigned int sym_ndx;
9367 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9368 relname = elf_ia64_reloc_type (r_type);
9370 /* PR 17531: file: 9fa67536. */
9371 if (relname == NULL)
9373 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9374 continue;
9377 if (! startswith (relname, "R_IA64_SEGREL"))
9379 warn (_("Skipping unexpected relocation type: %s\n"), relname);
9380 continue;
9383 i = rp->r_offset / (3 * eh_addr_size);
9385 /* PR 17531: file: 5bc8d9bf. */
9386 if (i >= aux->table_len)
9388 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9390 continue;
9393 sym_ndx = get_reloc_symindex (rp->r_info);
9394 if (sym_ndx >= aux->nsyms)
9396 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9397 sym_ndx);
9398 continue;
9400 sym = aux->symtab + sym_ndx;
9402 switch (rp->r_offset / eh_addr_size % 3)
9404 case 0:
9405 aux->table[i].start.section = sym->st_shndx;
9406 aux->table[i].start.offset = rp->r_addend + sym->st_value;
9407 break;
9408 case 1:
9409 aux->table[i].end.section = sym->st_shndx;
9410 aux->table[i].end.offset = rp->r_addend + sym->st_value;
9411 break;
9412 case 2:
9413 aux->table[i].info.section = sym->st_shndx;
9414 aux->table[i].info.offset = rp->r_addend + sym->st_value;
9415 break;
9416 default:
9417 break;
9421 free (rela);
9424 return true;
9427 static bool
9428 ia64_process_unwind (Filedata * filedata)
9430 Elf_Internal_Shdr * sec;
9431 Elf_Internal_Shdr * unwsec = NULL;
9432 uint64_t i, unwcount = 0, unwstart = 0;
9433 struct ia64_unw_aux_info aux;
9434 bool res = true;
9436 memset (& aux, 0, sizeof (aux));
9438 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
9440 if (sec->sh_type == SHT_SYMTAB)
9442 if (aux.symtab)
9444 error (_("Multiple symbol tables encountered\n"));
9445 free (aux.symtab);
9446 aux.symtab = NULL;
9447 free (aux.strtab);
9448 aux.strtab = NULL;
9450 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9451 &aux.strtab, &aux.strtab_size))
9452 return false;
9454 else if (sec->sh_type == SHT_IA_64_UNWIND)
9455 unwcount++;
9458 if (!unwcount)
9459 printf (_("\nThere are no unwind sections in this file.\n"));
9461 while (unwcount-- > 0)
9463 const char *suffix;
9464 size_t len, len2;
9466 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
9467 i < filedata->file_header.e_shnum; ++i, ++sec)
9468 if (sec->sh_type == SHT_IA_64_UNWIND)
9470 unwsec = sec;
9471 break;
9473 /* We have already counted the number of SHT_IA64_UNWIND
9474 sections so the loop above should never fail. */
9475 assert (unwsec != NULL);
9477 unwstart = i + 1;
9478 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
9480 if ((unwsec->sh_flags & SHF_GROUP) != 0)
9482 /* We need to find which section group it is in. */
9483 struct group_list * g;
9485 if (filedata->section_headers_groups == NULL
9486 || filedata->section_headers_groups[i] == NULL)
9487 i = filedata->file_header.e_shnum;
9488 else
9490 g = filedata->section_headers_groups[i]->root;
9492 for (; g != NULL; g = g->next)
9494 sec = filedata->section_headers + g->section_index;
9496 if (section_name_valid (filedata, sec)
9497 && streq (section_name (filedata, sec),
9498 ELF_STRING_ia64_unwind_info))
9499 break;
9502 if (g == NULL)
9503 i = filedata->file_header.e_shnum;
9506 else if (section_name_valid (filedata, unwsec)
9507 && startswith (section_name (filedata, unwsec),
9508 ELF_STRING_ia64_unwind_once))
9510 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
9511 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
9512 suffix = section_name (filedata, unwsec) + len;
9513 for (i = 0, sec = filedata->section_headers;
9514 i < filedata->file_header.e_shnum;
9515 ++i, ++sec)
9516 if (section_name_valid (filedata, sec)
9517 && startswith (section_name (filedata, sec),
9518 ELF_STRING_ia64_unwind_info_once)
9519 && streq (section_name (filedata, sec) + len2, suffix))
9520 break;
9522 else
9524 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
9525 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
9526 len = sizeof (ELF_STRING_ia64_unwind) - 1;
9527 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
9528 suffix = "";
9529 if (section_name_valid (filedata, unwsec)
9530 && startswith (section_name (filedata, unwsec),
9531 ELF_STRING_ia64_unwind))
9532 suffix = section_name (filedata, unwsec) + len;
9533 for (i = 0, sec = filedata->section_headers;
9534 i < filedata->file_header.e_shnum;
9535 ++i, ++sec)
9536 if (section_name_valid (filedata, sec)
9537 && startswith (section_name (filedata, sec),
9538 ELF_STRING_ia64_unwind_info)
9539 && streq (section_name (filedata, sec) + len2, suffix))
9540 break;
9543 if (i == filedata->file_header.e_shnum)
9545 printf (_("\nCould not find unwind info section for "));
9547 if (filedata->string_table == NULL)
9548 printf ("%d", unwsec->sh_name);
9549 else
9550 printf ("'%s'", printable_section_name (filedata, unwsec));
9552 else
9554 aux.info_addr = sec->sh_addr;
9555 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
9556 sec->sh_size,
9557 _("unwind info"));
9558 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
9560 printf (_("\nUnwind section "));
9562 if (filedata->string_table == NULL)
9563 printf ("%d", unwsec->sh_name);
9564 else
9565 printf ("'%s'", printable_section_name (filedata, unwsec));
9567 printf (_(" at offset %#" PRIx64 " contains %" PRIu64 " entries:\n"),
9568 unwsec->sh_offset,
9569 unwsec->sh_size / (3 * eh_addr_size));
9571 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
9572 && aux.table_len > 0)
9573 dump_ia64_unwind (filedata, & aux);
9575 free ((char *) aux.table);
9576 free ((char *) aux.info);
9577 aux.table = NULL;
9578 aux.info = NULL;
9582 free (aux.symtab);
9583 free ((char *) aux.strtab);
9585 return res;
9588 struct hppa_unw_table_entry
9590 struct absaddr start;
9591 struct absaddr end;
9592 unsigned int Cannot_unwind:1; /* 0 */
9593 unsigned int Millicode:1; /* 1 */
9594 unsigned int Millicode_save_sr0:1; /* 2 */
9595 unsigned int Region_description:2; /* 3..4 */
9596 unsigned int reserved1:1; /* 5 */
9597 unsigned int Entry_SR:1; /* 6 */
9598 unsigned int Entry_FR:4; /* Number saved 7..10 */
9599 unsigned int Entry_GR:5; /* Number saved 11..15 */
9600 unsigned int Args_stored:1; /* 16 */
9601 unsigned int Variable_Frame:1; /* 17 */
9602 unsigned int Separate_Package_Body:1; /* 18 */
9603 unsigned int Frame_Extension_Millicode:1; /* 19 */
9604 unsigned int Stack_Overflow_Check:1; /* 20 */
9605 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
9606 unsigned int Ada_Region:1; /* 22 */
9607 unsigned int cxx_info:1; /* 23 */
9608 unsigned int cxx_try_catch:1; /* 24 */
9609 unsigned int sched_entry_seq:1; /* 25 */
9610 unsigned int reserved2:1; /* 26 */
9611 unsigned int Save_SP:1; /* 27 */
9612 unsigned int Save_RP:1; /* 28 */
9613 unsigned int Save_MRP_in_frame:1; /* 29 */
9614 unsigned int extn_ptr_defined:1; /* 30 */
9615 unsigned int Cleanup_defined:1; /* 31 */
9617 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
9618 unsigned int HP_UX_interrupt_marker:1; /* 1 */
9619 unsigned int Large_frame:1; /* 2 */
9620 unsigned int Pseudo_SP_Set:1; /* 3 */
9621 unsigned int reserved4:1; /* 4 */
9622 unsigned int Total_frame_size:27; /* 5..31 */
9625 struct hppa_unw_aux_info
9627 struct hppa_unw_table_entry * table; /* Unwind table. */
9628 uint64_t table_len; /* Length of unwind table. */
9629 uint64_t seg_base; /* Starting address of segment. */
9630 Elf_Internal_Sym * symtab; /* The symbol table. */
9631 uint64_t nsyms; /* Number of symbols. */
9632 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9633 uint64_t nfuns; /* Number of entries in funtab. */
9634 char * strtab; /* The string table. */
9635 uint64_t strtab_size; /* Size of string table. */
9638 static bool
9639 dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
9641 struct hppa_unw_table_entry * tp;
9642 uint64_t j, nfuns;
9643 bool res = true;
9645 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9646 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9647 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9648 aux->funtab[nfuns++] = aux->symtab[j];
9649 aux->nfuns = nfuns;
9650 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9652 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9654 uint64_t offset;
9655 const char * procname;
9657 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
9658 aux->strtab_size, tp->start, &procname,
9659 &offset);
9661 fputs ("\n<", stdout);
9663 if (procname)
9665 fputs (procname, stdout);
9667 if (offset)
9668 printf ("+%" PRIx64, offset);
9671 fputs (">: [", stdout);
9672 print_vma (tp->start.offset, PREFIX_HEX);
9673 fputc ('-', stdout);
9674 print_vma (tp->end.offset, PREFIX_HEX);
9675 printf ("]\n\t");
9677 #define PF(_m) if (tp->_m) printf (#_m " ");
9678 #define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
9679 PF(Cannot_unwind);
9680 PF(Millicode);
9681 PF(Millicode_save_sr0);
9682 /* PV(Region_description); */
9683 PF(Entry_SR);
9684 PV(Entry_FR);
9685 PV(Entry_GR);
9686 PF(Args_stored);
9687 PF(Variable_Frame);
9688 PF(Separate_Package_Body);
9689 PF(Frame_Extension_Millicode);
9690 PF(Stack_Overflow_Check);
9691 PF(Two_Instruction_SP_Increment);
9692 PF(Ada_Region);
9693 PF(cxx_info);
9694 PF(cxx_try_catch);
9695 PF(sched_entry_seq);
9696 PF(Save_SP);
9697 PF(Save_RP);
9698 PF(Save_MRP_in_frame);
9699 PF(extn_ptr_defined);
9700 PF(Cleanup_defined);
9701 PF(MPE_XL_interrupt_marker);
9702 PF(HP_UX_interrupt_marker);
9703 PF(Large_frame);
9704 PF(Pseudo_SP_Set);
9705 PV(Total_frame_size);
9706 #undef PF
9707 #undef PV
9710 printf ("\n");
9712 free (aux->funtab);
9714 return res;
9717 static bool
9718 slurp_hppa_unwind_table (Filedata * filedata,
9719 struct hppa_unw_aux_info * aux,
9720 Elf_Internal_Shdr * sec)
9722 uint64_t size, unw_ent_size, nentries, nrelas, i;
9723 Elf_Internal_Phdr * seg;
9724 struct hppa_unw_table_entry * tep;
9725 Elf_Internal_Shdr * relsec;
9726 Elf_Internal_Rela * rela;
9727 Elf_Internal_Rela * rp;
9728 unsigned char * table;
9729 unsigned char * tp;
9730 Elf_Internal_Sym * sym;
9731 const char * relname;
9733 /* First, find the starting address of the segment that includes
9734 this section. */
9735 if (filedata->file_header.e_phnum)
9737 if (! get_program_headers (filedata))
9738 return false;
9740 for (seg = filedata->program_headers;
9741 seg < filedata->program_headers + filedata->file_header.e_phnum;
9742 ++seg)
9744 if (seg->p_type != PT_LOAD)
9745 continue;
9747 if (sec->sh_addr >= seg->p_vaddr
9748 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9750 aux->seg_base = seg->p_vaddr;
9751 break;
9756 /* Second, build the unwind table from the contents of the unwind
9757 section. */
9758 size = sec->sh_size;
9759 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
9760 _("unwind table"));
9761 if (!table)
9762 return false;
9764 unw_ent_size = 16;
9765 nentries = size / unw_ent_size;
9766 size = unw_ent_size * nentries;
9768 aux->table_len = nentries;
9769 tep = aux->table = (struct hppa_unw_table_entry *)
9770 xcmalloc (nentries, sizeof (aux->table[0]));
9772 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
9774 unsigned int tmp1, tmp2;
9776 tep->start.section = SHN_UNDEF;
9777 tep->end.section = SHN_UNDEF;
9779 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9780 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9781 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9782 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9784 tep->start.offset += aux->seg_base;
9785 tep->end.offset += aux->seg_base;
9787 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9788 tep->Millicode = (tmp1 >> 30) & 0x1;
9789 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9790 tep->Region_description = (tmp1 >> 27) & 0x3;
9791 tep->reserved1 = (tmp1 >> 26) & 0x1;
9792 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9793 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9794 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9795 tep->Args_stored = (tmp1 >> 15) & 0x1;
9796 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9797 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9798 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9799 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9800 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9801 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9802 tep->cxx_info = (tmp1 >> 8) & 0x1;
9803 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9804 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9805 tep->reserved2 = (tmp1 >> 5) & 0x1;
9806 tep->Save_SP = (tmp1 >> 4) & 0x1;
9807 tep->Save_RP = (tmp1 >> 3) & 0x1;
9808 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9809 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9810 tep->Cleanup_defined = tmp1 & 0x1;
9812 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9813 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9814 tep->Large_frame = (tmp2 >> 29) & 0x1;
9815 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9816 tep->reserved4 = (tmp2 >> 27) & 0x1;
9817 tep->Total_frame_size = tmp2 & 0x7ffffff;
9819 free (table);
9821 /* Third, apply any relocations to the unwind table. */
9822 for (relsec = filedata->section_headers;
9823 relsec < filedata->section_headers + filedata->file_header.e_shnum;
9824 ++relsec)
9826 if (relsec->sh_type != SHT_RELA
9827 || relsec->sh_info >= filedata->file_header.e_shnum
9828 || filedata->section_headers + relsec->sh_info != sec)
9829 continue;
9831 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
9832 & rela, & nrelas))
9833 return false;
9835 for (rp = rela; rp < rela + nrelas; ++rp)
9837 unsigned int sym_ndx;
9838 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9839 relname = elf_hppa_reloc_type (r_type);
9841 if (relname == NULL)
9843 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9844 continue;
9847 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
9848 if (! startswith (relname, "R_PARISC_SEGREL"))
9850 warn (_("Skipping unexpected relocation type: %s\n"), relname);
9851 continue;
9854 i = rp->r_offset / unw_ent_size;
9855 if (i >= aux->table_len)
9857 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9859 continue;
9862 sym_ndx = get_reloc_symindex (rp->r_info);
9863 if (sym_ndx >= aux->nsyms)
9865 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9866 sym_ndx);
9867 continue;
9869 sym = aux->symtab + sym_ndx;
9871 switch ((rp->r_offset % unw_ent_size) / 4)
9873 case 0:
9874 aux->table[i].start.section = sym->st_shndx;
9875 aux->table[i].start.offset = sym->st_value + rp->r_addend;
9876 break;
9877 case 1:
9878 aux->table[i].end.section = sym->st_shndx;
9879 aux->table[i].end.offset = sym->st_value + rp->r_addend;
9880 break;
9881 default:
9882 break;
9886 free (rela);
9889 return true;
9892 static bool
9893 hppa_process_unwind (Filedata * filedata)
9895 struct hppa_unw_aux_info aux;
9896 Elf_Internal_Shdr * unwsec = NULL;
9897 Elf_Internal_Shdr * sec;
9898 size_t i;
9899 bool res = true;
9901 if (filedata->string_table == NULL)
9902 return false;
9904 memset (& aux, 0, sizeof (aux));
9906 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
9908 if (sec->sh_type == SHT_SYMTAB)
9910 if (aux.symtab)
9912 error (_("Multiple symbol tables encountered\n"));
9913 free (aux.symtab);
9914 aux.symtab = NULL;
9915 free (aux.strtab);
9916 aux.strtab = NULL;
9918 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9919 &aux.strtab, &aux.strtab_size))
9920 return false;
9922 else if (section_name_valid (filedata, sec)
9923 && streq (section_name (filedata, sec), ".PARISC.unwind"))
9924 unwsec = sec;
9927 if (!unwsec)
9928 printf (_("\nThere are no unwind sections in this file.\n"));
9930 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
9932 if (section_name_valid (filedata, sec)
9933 && streq (section_name (filedata, sec), ".PARISC.unwind"))
9935 uint64_t num_unwind = sec->sh_size / 16;
9937 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
9938 "contains %" PRIu64 " entry:\n",
9939 "\nUnwind section '%s' at offset %#" PRIx64 " "
9940 "contains %" PRIu64 " entries:\n",
9941 num_unwind),
9942 printable_section_name (filedata, sec),
9943 sec->sh_offset,
9944 num_unwind);
9946 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
9947 res = false;
9949 if (res && aux.table_len > 0)
9951 if (! dump_hppa_unwind (filedata, &aux))
9952 res = false;
9955 free ((char *) aux.table);
9956 aux.table = NULL;
9960 free (aux.symtab);
9961 free ((char *) aux.strtab);
9963 return res;
9966 struct arm_section
9968 unsigned char * data; /* The unwind data. */
9969 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9970 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
9971 uint64_t nrelas; /* The number of relocations. */
9972 unsigned int rel_type; /* REL or RELA ? */
9973 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
9976 struct arm_unw_aux_info
9978 Filedata * filedata; /* The file containing the unwind sections. */
9979 Elf_Internal_Sym * symtab; /* The file's symbol table. */
9980 uint64_t nsyms; /* Number of symbols. */
9981 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9982 uint64_t nfuns; /* Number of these symbols. */
9983 char * strtab; /* The file's string table. */
9984 uint64_t strtab_size; /* Size of string table. */
9987 static const char *
9988 arm_print_vma_and_name (Filedata * filedata,
9989 struct arm_unw_aux_info * aux,
9990 uint64_t fn,
9991 struct absaddr addr)
9993 const char *procname;
9994 uint64_t sym_offset;
9996 if (addr.section == SHN_UNDEF)
9997 addr.offset = fn;
9999 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
10000 aux->strtab_size, addr, &procname,
10001 &sym_offset);
10003 print_vma (fn, PREFIX_HEX);
10005 if (procname)
10007 fputs (" <", stdout);
10008 fputs (procname, stdout);
10010 if (sym_offset)
10011 printf ("+0x%" PRIx64, sym_offset);
10012 fputc ('>', stdout);
10015 return procname;
10018 static void
10019 arm_free_section (struct arm_section *arm_sec)
10021 free (arm_sec->data);
10022 free (arm_sec->rela);
10025 /* 1) If SEC does not match the one cached in ARM_SEC, then free the current
10026 cached section and install SEC instead.
10027 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
10028 and return its valued in * WORDP, relocating if necessary.
10029 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
10030 relocation's offset in ADDR.
10031 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
10032 into the string table of the symbol associated with the reloc. If no
10033 reloc was applied store -1 there.
10034 5) Return TRUE upon success, FALSE otherwise. */
10036 static bool
10037 get_unwind_section_word (Filedata * filedata,
10038 struct arm_unw_aux_info * aux,
10039 struct arm_section * arm_sec,
10040 Elf_Internal_Shdr * sec,
10041 uint64_t word_offset,
10042 unsigned int * wordp,
10043 struct absaddr * addr,
10044 uint64_t * sym_name)
10046 Elf_Internal_Rela *rp;
10047 Elf_Internal_Sym *sym;
10048 const char * relname;
10049 unsigned int word;
10050 bool wrapped;
10052 if (sec == NULL || arm_sec == NULL)
10053 return false;
10055 addr->section = SHN_UNDEF;
10056 addr->offset = 0;
10058 if (sym_name != NULL)
10059 *sym_name = (uint64_t) -1;
10061 /* If necessary, update the section cache. */
10062 if (sec != arm_sec->sec)
10064 Elf_Internal_Shdr *relsec;
10066 arm_free_section (arm_sec);
10068 arm_sec->sec = sec;
10069 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
10070 sec->sh_size, _("unwind data"));
10071 arm_sec->rela = NULL;
10072 arm_sec->nrelas = 0;
10074 for (relsec = filedata->section_headers;
10075 relsec < filedata->section_headers + filedata->file_header.e_shnum;
10076 ++relsec)
10078 if (relsec->sh_info >= filedata->file_header.e_shnum
10079 || filedata->section_headers + relsec->sh_info != sec
10080 /* PR 15745: Check the section type as well. */
10081 || (relsec->sh_type != SHT_REL
10082 && relsec->sh_type != SHT_RELA))
10083 continue;
10085 arm_sec->rel_type = relsec->sh_type;
10086 if (relsec->sh_type == SHT_REL)
10088 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
10089 relsec->sh_size,
10090 & arm_sec->rela, & arm_sec->nrelas))
10091 return false;
10093 else /* relsec->sh_type == SHT_RELA */
10095 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
10096 relsec->sh_size,
10097 & arm_sec->rela, & arm_sec->nrelas))
10098 return false;
10100 break;
10103 arm_sec->next_rela = arm_sec->rela;
10106 /* If there is no unwind data we can do nothing. */
10107 if (arm_sec->data == NULL)
10108 return false;
10110 /* If the offset is invalid then fail. */
10111 if (/* PR 21343 *//* PR 18879 */
10112 sec->sh_size < 4
10113 || word_offset > sec->sh_size - 4)
10114 return false;
10116 /* Get the word at the required offset. */
10117 word = byte_get (arm_sec->data + word_offset, 4);
10119 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
10120 if (arm_sec->rela == NULL)
10122 * wordp = word;
10123 return true;
10126 /* Look through the relocs to find the one that applies to the provided offset. */
10127 wrapped = false;
10128 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
10130 uint64_t prelval, offset;
10132 if (rp->r_offset > word_offset && !wrapped)
10134 rp = arm_sec->rela;
10135 wrapped = true;
10137 if (rp->r_offset > word_offset)
10138 break;
10140 if (rp->r_offset & 3)
10142 warn (_("Skipping unexpected relocation at offset %#" PRIx64 "\n"),
10143 rp->r_offset);
10144 continue;
10147 if (rp->r_offset < word_offset)
10148 continue;
10150 /* PR 17531: file: 027-161405-0.004 */
10151 if (aux->symtab == NULL)
10152 continue;
10154 if (arm_sec->rel_type == SHT_REL)
10156 offset = word & 0x7fffffff;
10157 if (offset & 0x40000000)
10158 offset |= ~ (uint64_t) 0x7fffffff;
10160 else if (arm_sec->rel_type == SHT_RELA)
10161 offset = rp->r_addend;
10162 else
10164 error (_("Unknown section relocation type %d encountered\n"),
10165 arm_sec->rel_type);
10166 break;
10169 /* PR 17531 file: 027-1241568-0.004. */
10170 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
10172 error (_("Bad symbol index in unwind relocation "
10173 "(%" PRIu64 " > %" PRIu64 ")\n"),
10174 ELF32_R_SYM (rp->r_info), aux->nsyms);
10175 break;
10178 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
10179 offset += sym->st_value;
10180 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
10182 /* Check that we are processing the expected reloc type. */
10183 if (filedata->file_header.e_machine == EM_ARM)
10185 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
10186 if (relname == NULL)
10188 warn (_("Skipping unknown ARM relocation type: %d\n"),
10189 (int) ELF32_R_TYPE (rp->r_info));
10190 continue;
10193 if (streq (relname, "R_ARM_NONE"))
10194 continue;
10196 if (! streq (relname, "R_ARM_PREL31"))
10198 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
10199 continue;
10202 else if (filedata->file_header.e_machine == EM_TI_C6000)
10204 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
10205 if (relname == NULL)
10207 warn (_("Skipping unknown C6000 relocation type: %d\n"),
10208 (int) ELF32_R_TYPE (rp->r_info));
10209 continue;
10212 if (streq (relname, "R_C6000_NONE"))
10213 continue;
10215 if (! streq (relname, "R_C6000_PREL31"))
10217 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
10218 continue;
10221 prelval >>= 1;
10223 else
10225 /* This function currently only supports ARM and TI unwinders. */
10226 warn (_("Only TI and ARM unwinders are currently supported\n"));
10227 break;
10230 word = (word & ~ (uint64_t) 0x7fffffff) | (prelval & 0x7fffffff);
10231 addr->section = sym->st_shndx;
10232 addr->offset = offset;
10234 if (sym_name)
10235 * sym_name = sym->st_name;
10236 break;
10239 *wordp = word;
10240 arm_sec->next_rela = rp;
10242 return true;
10245 static const char *tic6x_unwind_regnames[16] =
10247 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
10248 "A14", "A13", "A12", "A11", "A10",
10249 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
10252 static void
10253 decode_tic6x_unwind_regmask (unsigned int mask)
10255 int i;
10257 for (i = 12; mask; mask >>= 1, i--)
10259 if (mask & 1)
10261 fputs (tic6x_unwind_regnames[i], stdout);
10262 if (mask > 1)
10263 fputs (", ", stdout);
10268 #define ADVANCE \
10269 if (remaining == 0 && more_words) \
10271 data_offset += 4; \
10272 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
10273 data_offset, & word, & addr, NULL)) \
10274 return false; \
10275 remaining = 4; \
10276 more_words--; \
10279 #define GET_OP(OP) \
10280 ADVANCE; \
10281 if (remaining) \
10283 remaining--; \
10284 (OP) = word >> 24; \
10285 word <<= 8; \
10287 else \
10289 printf (_("[Truncated opcode]\n")); \
10290 return false; \
10292 printf ("0x%02x ", OP)
10294 static bool
10295 decode_arm_unwind_bytecode (Filedata * filedata,
10296 struct arm_unw_aux_info * aux,
10297 unsigned int word,
10298 unsigned int remaining,
10299 unsigned int more_words,
10300 uint64_t data_offset,
10301 Elf_Internal_Shdr * data_sec,
10302 struct arm_section * data_arm_sec)
10304 struct absaddr addr;
10305 bool res = true;
10307 /* Decode the unwinding instructions. */
10308 while (1)
10310 unsigned int op, op2;
10312 ADVANCE;
10313 if (remaining == 0)
10314 break;
10315 remaining--;
10316 op = word >> 24;
10317 word <<= 8;
10319 printf (" 0x%02x ", op);
10321 if ((op & 0xc0) == 0x00)
10323 int offset = ((op & 0x3f) << 2) + 4;
10325 printf (" vsp = vsp + %d", offset);
10327 else if ((op & 0xc0) == 0x40)
10329 int offset = ((op & 0x3f) << 2) + 4;
10331 printf (" vsp = vsp - %d", offset);
10333 else if ((op & 0xf0) == 0x80)
10335 GET_OP (op2);
10336 if (op == 0x80 && op2 == 0)
10337 printf (_("Refuse to unwind"));
10338 else
10340 unsigned int mask = ((op & 0x0f) << 8) | op2;
10341 bool first = true;
10342 int i;
10344 printf ("pop {");
10345 for (i = 0; i < 12; i++)
10346 if (mask & (1 << i))
10348 if (first)
10349 first = false;
10350 else
10351 printf (", ");
10352 printf ("r%d", 4 + i);
10354 printf ("}");
10357 else if ((op & 0xf0) == 0x90)
10359 if (op == 0x9d || op == 0x9f)
10360 printf (_(" [Reserved]"));
10361 else
10362 printf (" vsp = r%d", op & 0x0f);
10364 else if ((op & 0xf0) == 0xa0)
10366 int end = 4 + (op & 0x07);
10367 bool first = true;
10368 int i;
10370 printf (" pop {");
10371 for (i = 4; i <= end; i++)
10373 if (first)
10374 first = false;
10375 else
10376 printf (", ");
10377 printf ("r%d", i);
10379 if (op & 0x08)
10381 if (!first)
10382 printf (", ");
10383 printf ("r14");
10385 printf ("}");
10387 else if (op == 0xb0)
10388 printf (_(" finish"));
10389 else if (op == 0xb1)
10391 GET_OP (op2);
10392 if (op2 == 0 || (op2 & 0xf0) != 0)
10393 printf (_("[Spare]"));
10394 else
10396 unsigned int mask = op2 & 0x0f;
10397 bool first = true;
10398 int i;
10400 printf ("pop {");
10401 for (i = 0; i < 12; i++)
10402 if (mask & (1 << i))
10404 if (first)
10405 first = false;
10406 else
10407 printf (", ");
10408 printf ("r%d", i);
10410 printf ("}");
10413 else if (op == 0xb2)
10415 unsigned char buf[9];
10416 unsigned int i, len;
10417 uint64_t offset;
10419 for (i = 0; i < sizeof (buf); i++)
10421 GET_OP (buf[i]);
10422 if ((buf[i] & 0x80) == 0)
10423 break;
10425 if (i == sizeof (buf))
10427 error (_("corrupt change to vsp\n"));
10428 res = false;
10430 else
10432 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
10433 assert (len == i + 1);
10434 offset = offset * 4 + 0x204;
10435 printf ("vsp = vsp + %" PRId64, offset);
10438 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
10440 unsigned int first, last;
10442 GET_OP (op2);
10443 first = op2 >> 4;
10444 last = op2 & 0x0f;
10445 if (op == 0xc8)
10446 first = first + 16;
10447 printf ("pop {D%d", first);
10448 if (last)
10449 printf ("-D%d", first + last);
10450 printf ("}");
10452 else if (op == 0xb4)
10453 printf (_(" pop {ra_auth_code}"));
10454 else if (op == 0xb5)
10455 printf (_(" vsp as modifier for PAC validation"));
10456 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
10458 unsigned int count = op & 0x07;
10460 printf ("pop {D8");
10461 if (count)
10462 printf ("-D%d", 8 + count);
10463 printf ("}");
10465 else if (op >= 0xc0 && op <= 0xc5)
10467 unsigned int count = op & 0x07;
10469 printf (" pop {wR10");
10470 if (count)
10471 printf ("-wR%d", 10 + count);
10472 printf ("}");
10474 else if (op == 0xc6)
10476 unsigned int first, last;
10478 GET_OP (op2);
10479 first = op2 >> 4;
10480 last = op2 & 0x0f;
10481 printf ("pop {wR%d", first);
10482 if (last)
10483 printf ("-wR%d", first + last);
10484 printf ("}");
10486 else if (op == 0xc7)
10488 GET_OP (op2);
10489 if (op2 == 0 || (op2 & 0xf0) != 0)
10490 printf (_("[Spare]"));
10491 else
10493 unsigned int mask = op2 & 0x0f;
10494 bool first = true;
10495 int i;
10497 printf ("pop {");
10498 for (i = 0; i < 4; i++)
10499 if (mask & (1 << i))
10501 if (first)
10502 first = false;
10503 else
10504 printf (", ");
10505 printf ("wCGR%d", i);
10507 printf ("}");
10510 else
10512 printf (_(" [unsupported opcode]"));
10513 res = false;
10516 printf ("\n");
10519 return res;
10522 static bool
10523 decode_tic6x_unwind_bytecode (Filedata * filedata,
10524 struct arm_unw_aux_info * aux,
10525 unsigned int word,
10526 unsigned int remaining,
10527 unsigned int more_words,
10528 uint64_t data_offset,
10529 Elf_Internal_Shdr * data_sec,
10530 struct arm_section * data_arm_sec)
10532 struct absaddr addr;
10534 /* Decode the unwinding instructions. */
10535 while (1)
10537 unsigned int op, op2;
10539 ADVANCE;
10540 if (remaining == 0)
10541 break;
10542 remaining--;
10543 op = word >> 24;
10544 word <<= 8;
10546 printf (" 0x%02x ", op);
10548 if ((op & 0xc0) == 0x00)
10550 int offset = ((op & 0x3f) << 3) + 8;
10551 printf (" sp = sp + %d", offset);
10553 else if ((op & 0xc0) == 0x80)
10555 GET_OP (op2);
10556 if (op == 0x80 && op2 == 0)
10557 printf (_("Refuse to unwind"));
10558 else
10560 unsigned int mask = ((op & 0x1f) << 8) | op2;
10561 if (op & 0x20)
10562 printf ("pop compact {");
10563 else
10564 printf ("pop {");
10566 decode_tic6x_unwind_regmask (mask);
10567 printf("}");
10570 else if ((op & 0xf0) == 0xc0)
10572 unsigned int reg;
10573 unsigned int nregs;
10574 unsigned int i;
10575 const char *name;
10576 struct
10578 unsigned int offset;
10579 unsigned int reg;
10580 } regpos[16];
10582 /* Scan entire instruction first so that GET_OP output is not
10583 interleaved with disassembly. */
10584 nregs = 0;
10585 for (i = 0; nregs < (op & 0xf); i++)
10587 GET_OP (op2);
10588 reg = op2 >> 4;
10589 if (reg != 0xf)
10591 regpos[nregs].offset = i * 2;
10592 regpos[nregs].reg = reg;
10593 nregs++;
10596 reg = op2 & 0xf;
10597 if (reg != 0xf)
10599 regpos[nregs].offset = i * 2 + 1;
10600 regpos[nregs].reg = reg;
10601 nregs++;
10605 printf (_("pop frame {"));
10606 if (nregs == 0)
10608 printf (_("*corrupt* - no registers specified"));
10610 else
10612 reg = nregs - 1;
10613 for (i = i * 2; i > 0; i--)
10615 if (regpos[reg].offset == i - 1)
10617 name = tic6x_unwind_regnames[regpos[reg].reg];
10618 if (reg > 0)
10619 reg--;
10621 else
10622 name = _("[pad]");
10624 fputs (name, stdout);
10625 if (i > 1)
10626 printf (", ");
10630 printf ("}");
10632 else if (op == 0xd0)
10633 printf (" MOV FP, SP");
10634 else if (op == 0xd1)
10635 printf (" __c6xabi_pop_rts");
10636 else if (op == 0xd2)
10638 unsigned char buf[9];
10639 unsigned int i, len;
10640 uint64_t offset;
10642 for (i = 0; i < sizeof (buf); i++)
10644 GET_OP (buf[i]);
10645 if ((buf[i] & 0x80) == 0)
10646 break;
10648 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10649 if (i == sizeof (buf))
10651 warn (_("Corrupt stack pointer adjustment detected\n"));
10652 return false;
10655 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
10656 assert (len == i + 1);
10657 offset = offset * 8 + 0x408;
10658 printf (_("sp = sp + %" PRId64), offset);
10660 else if ((op & 0xf0) == 0xe0)
10662 if ((op & 0x0f) == 7)
10663 printf (" RETURN");
10664 else
10665 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10667 else
10669 printf (_(" [unsupported opcode]"));
10671 putchar ('\n');
10674 return true;
10677 static uint64_t
10678 arm_expand_prel31 (Filedata * filedata, uint64_t word, uint64_t where)
10680 uint64_t offset;
10682 offset = word & 0x7fffffff;
10683 if (offset & 0x40000000)
10684 offset |= ~ (uint64_t) 0x7fffffff;
10686 if (filedata->file_header.e_machine == EM_TI_C6000)
10687 offset <<= 1;
10689 return offset + where;
10692 static bool
10693 decode_arm_unwind (Filedata * filedata,
10694 struct arm_unw_aux_info * aux,
10695 unsigned int word,
10696 unsigned int remaining,
10697 uint64_t data_offset,
10698 Elf_Internal_Shdr * data_sec,
10699 struct arm_section * data_arm_sec)
10701 int per_index;
10702 unsigned int more_words = 0;
10703 struct absaddr addr;
10704 uint64_t sym_name = (uint64_t) -1;
10705 bool res = true;
10707 if (remaining == 0)
10709 /* Fetch the first word.
10710 Note - when decoding an object file the address extracted
10711 here will always be 0. So we also pass in the sym_name
10712 parameter so that we can find the symbol associated with
10713 the personality routine. */
10714 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
10715 & word, & addr, & sym_name))
10716 return false;
10718 remaining = 4;
10720 else
10722 addr.section = SHN_UNDEF;
10723 addr.offset = 0;
10726 if ((word & 0x80000000) == 0)
10728 /* Expand prel31 for personality routine. */
10729 uint64_t fn;
10730 const char *procname;
10732 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
10733 printf (_(" Personality routine: "));
10734 if (fn == 0
10735 && addr.section == SHN_UNDEF && addr.offset == 0
10736 && sym_name != (uint64_t) -1 && sym_name < aux->strtab_size)
10738 procname = aux->strtab + sym_name;
10739 print_vma (fn, PREFIX_HEX);
10740 if (procname)
10742 fputs (" <", stdout);
10743 fputs (procname, stdout);
10744 fputc ('>', stdout);
10747 else
10748 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
10749 fputc ('\n', stdout);
10751 /* The GCC personality routines use the standard compact
10752 encoding, starting with one byte giving the number of
10753 words. */
10754 if (procname != NULL
10755 && (startswith (procname, "__gcc_personality_v0")
10756 || startswith (procname, "__gxx_personality_v0")
10757 || startswith (procname, "__gcj_personality_v0")
10758 || startswith (procname, "__gnu_objc_personality_v0")))
10760 remaining = 0;
10761 more_words = 1;
10762 ADVANCE;
10763 if (!remaining)
10765 printf (_(" [Truncated data]\n"));
10766 return false;
10768 more_words = word >> 24;
10769 word <<= 8;
10770 remaining--;
10771 per_index = -1;
10773 else
10774 return true;
10776 else
10778 /* ARM EHABI Section 6.3:
10780 An exception-handling table entry for the compact model looks like:
10782 31 30-28 27-24 23-0
10783 -- ----- ----- ----
10784 1 0 index Data for personalityRoutine[index] */
10786 if (filedata->file_header.e_machine == EM_ARM
10787 && (word & 0x70000000))
10789 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
10790 res = false;
10793 per_index = (word >> 24) & 0x7f;
10794 printf (_(" Compact model index: %d\n"), per_index);
10795 if (per_index == 0)
10797 more_words = 0;
10798 word <<= 8;
10799 remaining--;
10801 else if (per_index < 3)
10803 more_words = (word >> 16) & 0xff;
10804 word <<= 16;
10805 remaining -= 2;
10809 switch (filedata->file_header.e_machine)
10811 case EM_ARM:
10812 if (per_index < 3)
10814 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
10815 data_offset, data_sec, data_arm_sec))
10816 res = false;
10818 else
10820 warn (_("Unknown ARM compact model index encountered\n"));
10821 printf (_(" [reserved]\n"));
10822 res = false;
10824 break;
10826 case EM_TI_C6000:
10827 if (per_index < 3)
10829 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
10830 data_offset, data_sec, data_arm_sec))
10831 res = false;
10833 else if (per_index < 5)
10835 if (((word >> 17) & 0x7f) == 0x7f)
10836 printf (_(" Restore stack from frame pointer\n"));
10837 else
10838 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10839 printf (_(" Registers restored: "));
10840 if (per_index == 4)
10841 printf (" (compact) ");
10842 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10843 putchar ('\n');
10844 printf (_(" Return register: %s\n"),
10845 tic6x_unwind_regnames[word & 0xf]);
10847 else
10848 printf (_(" [reserved (%d)]\n"), per_index);
10849 break;
10851 default:
10852 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
10853 filedata->file_header.e_machine);
10854 res = false;
10857 /* Decode the descriptors. Not implemented. */
10859 return res;
10862 static bool
10863 dump_arm_unwind (Filedata * filedata,
10864 struct arm_unw_aux_info * aux,
10865 Elf_Internal_Shdr * exidx_sec)
10867 struct arm_section exidx_arm_sec, extab_arm_sec;
10868 unsigned int i, exidx_len;
10869 uint64_t j, nfuns;
10870 bool res = true;
10872 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10873 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10874 exidx_len = exidx_sec->sh_size / 8;
10876 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10877 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10878 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10879 aux->funtab[nfuns++] = aux->symtab[j];
10880 aux->nfuns = nfuns;
10881 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10883 for (i = 0; i < exidx_len; i++)
10885 unsigned int exidx_fn, exidx_entry;
10886 struct absaddr fn_addr, entry_addr;
10887 uint64_t fn;
10889 fputc ('\n', stdout);
10891 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
10892 8 * i, & exidx_fn, & fn_addr, NULL)
10893 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
10894 8 * i + 4, & exidx_entry, & entry_addr, NULL))
10896 free (aux->funtab);
10897 arm_free_section (& exidx_arm_sec);
10898 arm_free_section (& extab_arm_sec);
10899 return false;
10902 /* ARM EHABI, Section 5:
10903 An index table entry consists of 2 words.
10904 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10905 if (exidx_fn & 0x80000000)
10907 warn (_("corrupt index table entry: %x\n"), exidx_fn);
10908 res = false;
10911 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
10913 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
10914 fputs (": ", stdout);
10916 if (exidx_entry == 1)
10918 print_vma (exidx_entry, PREFIX_HEX);
10919 fputs (" [cantunwind]\n", stdout);
10921 else if (exidx_entry & 0x80000000)
10923 print_vma (exidx_entry, PREFIX_HEX);
10924 fputc ('\n', stdout);
10925 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
10927 else
10929 uint64_t table, table_offset = 0;
10930 Elf_Internal_Shdr *table_sec;
10932 fputs ("@", stdout);
10933 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
10934 print_vma (table, PREFIX_HEX);
10935 printf ("\n");
10937 /* Locate the matching .ARM.extab. */
10938 if (entry_addr.section != SHN_UNDEF
10939 && entry_addr.section < filedata->file_header.e_shnum)
10941 table_sec = filedata->section_headers + entry_addr.section;
10942 table_offset = entry_addr.offset;
10943 /* PR 18879 */
10944 if (table_offset > table_sec->sh_size)
10946 warn (_("Unwind entry contains corrupt offset (%#" PRIx64 ") into section %s\n"),
10947 table_offset,
10948 printable_section_name (filedata, table_sec));
10949 res = false;
10950 continue;
10953 else
10955 table_sec = find_section_by_address (filedata, table);
10956 if (table_sec != NULL)
10957 table_offset = table - table_sec->sh_addr;
10960 if (table_sec == NULL)
10962 warn (_("Could not locate .ARM.extab section containing %#" PRIx64 ".\n"),
10963 table);
10964 res = false;
10965 continue;
10968 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
10969 &extab_arm_sec))
10970 res = false;
10974 printf ("\n");
10976 free (aux->funtab);
10977 arm_free_section (&exidx_arm_sec);
10978 arm_free_section (&extab_arm_sec);
10980 return res;
10983 /* Used for both ARM and C6X unwinding tables. */
10985 static bool
10986 arm_process_unwind (Filedata * filedata)
10988 struct arm_unw_aux_info aux;
10989 Elf_Internal_Shdr *unwsec = NULL;
10990 Elf_Internal_Shdr *sec;
10991 size_t i;
10992 unsigned int sec_type;
10993 bool res = true;
10995 switch (filedata->file_header.e_machine)
10997 case EM_ARM:
10998 sec_type = SHT_ARM_EXIDX;
10999 break;
11001 case EM_TI_C6000:
11002 sec_type = SHT_C6000_UNWIND;
11003 break;
11005 default:
11006 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
11007 filedata->file_header.e_machine);
11008 return false;
11011 if (filedata->string_table == NULL)
11012 return false;
11014 memset (& aux, 0, sizeof (aux));
11015 aux.filedata = filedata;
11017 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
11019 if (sec->sh_type == SHT_SYMTAB)
11021 if (aux.symtab)
11023 error (_("Multiple symbol tables encountered\n"));
11024 free (aux.symtab);
11025 aux.symtab = NULL;
11026 free (aux.strtab);
11027 aux.strtab = NULL;
11029 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
11030 &aux.strtab, &aux.strtab_size))
11031 return false;
11033 else if (sec->sh_type == sec_type)
11034 unwsec = sec;
11037 if (unwsec == NULL)
11038 printf (_("\nThere are no unwind sections in this file.\n"));
11039 else
11040 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
11042 if (sec->sh_type == sec_type)
11044 uint64_t num_unwind = sec->sh_size / (2 * eh_addr_size);
11045 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
11046 "contains %" PRIu64 " entry:\n",
11047 "\nUnwind section '%s' at offset %#" PRIx64 " "
11048 "contains %" PRIu64 " entries:\n",
11049 num_unwind),
11050 printable_section_name (filedata, sec),
11051 sec->sh_offset,
11052 num_unwind);
11054 if (! dump_arm_unwind (filedata, &aux, sec))
11055 res = false;
11059 free (aux.symtab);
11060 free ((char *) aux.strtab);
11062 return res;
11065 static bool
11066 no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
11068 printf (_("No processor specific unwind information to decode\n"));
11069 return true;
11072 static bool
11073 process_unwind (Filedata * filedata)
11075 struct unwind_handler
11077 unsigned int machtype;
11078 bool (* handler)(Filedata *);
11079 } handlers[] =
11081 { EM_ARM, arm_process_unwind },
11082 { EM_IA_64, ia64_process_unwind },
11083 { EM_PARISC, hppa_process_unwind },
11084 { EM_TI_C6000, arm_process_unwind },
11085 { EM_386, no_processor_specific_unwind },
11086 { EM_X86_64, no_processor_specific_unwind },
11087 { 0, NULL }
11089 int i;
11091 if (!do_unwind)
11092 return true;
11094 for (i = 0; handlers[i].handler != NULL; i++)
11095 if (filedata->file_header.e_machine == handlers[i].machtype)
11096 return handlers[i].handler (filedata);
11098 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
11099 get_machine_name (filedata->file_header.e_machine));
11100 return true;
11103 static void
11104 dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
11106 switch (entry->d_tag)
11108 case DT_AARCH64_BTI_PLT:
11109 case DT_AARCH64_PAC_PLT:
11110 break;
11111 default:
11112 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11113 break;
11115 putchar ('\n');
11118 static void
11119 dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
11121 switch (entry->d_tag)
11123 case DT_MIPS_FLAGS:
11124 if (entry->d_un.d_val == 0)
11125 printf (_("NONE"));
11126 else
11128 static const char * opts[] =
11130 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
11131 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
11132 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
11133 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
11134 "RLD_ORDER_SAFE"
11136 unsigned int cnt;
11137 bool first = true;
11139 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
11140 if (entry->d_un.d_val & (1 << cnt))
11142 printf ("%s%s", first ? "" : " ", opts[cnt]);
11143 first = false;
11146 break;
11148 case DT_MIPS_IVERSION:
11149 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11150 printf (_("Interface Version: %s"),
11151 get_dynamic_name (filedata, entry->d_un.d_val));
11152 else
11153 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
11154 entry->d_un.d_ptr);
11155 break;
11157 case DT_MIPS_TIME_STAMP:
11159 char timebuf[128];
11160 struct tm * tmp;
11161 time_t atime = entry->d_un.d_val;
11163 tmp = gmtime (&atime);
11164 /* PR 17531: file: 6accc532. */
11165 if (tmp == NULL)
11166 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
11167 else
11168 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
11169 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11170 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
11171 printf (_("Time Stamp: %s"), timebuf);
11173 break;
11175 case DT_MIPS_RLD_VERSION:
11176 case DT_MIPS_LOCAL_GOTNO:
11177 case DT_MIPS_CONFLICTNO:
11178 case DT_MIPS_LIBLISTNO:
11179 case DT_MIPS_SYMTABNO:
11180 case DT_MIPS_UNREFEXTNO:
11181 case DT_MIPS_HIPAGENO:
11182 case DT_MIPS_DELTA_CLASS_NO:
11183 case DT_MIPS_DELTA_INSTANCE_NO:
11184 case DT_MIPS_DELTA_RELOC_NO:
11185 case DT_MIPS_DELTA_SYM_NO:
11186 case DT_MIPS_DELTA_CLASSSYM_NO:
11187 case DT_MIPS_COMPACT_SIZE:
11188 print_vma (entry->d_un.d_val, DEC);
11189 break;
11191 case DT_MIPS_XHASH:
11192 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11193 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
11194 /* Falls through. */
11196 default:
11197 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11199 putchar ('\n');
11202 static void
11203 dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
11205 switch (entry->d_tag)
11207 case DT_HP_DLD_FLAGS:
11209 static struct
11211 unsigned int bit;
11212 const char * str;
11214 flags[] =
11216 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
11217 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
11218 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
11219 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
11220 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
11221 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
11222 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
11223 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
11224 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
11225 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
11226 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
11227 { DT_HP_GST, "HP_GST" },
11228 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
11229 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
11230 { DT_HP_NODELETE, "HP_NODELETE" },
11231 { DT_HP_GROUP, "HP_GROUP" },
11232 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
11234 bool first = true;
11235 size_t cnt;
11236 uint64_t val = entry->d_un.d_val;
11238 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
11239 if (val & flags[cnt].bit)
11241 if (! first)
11242 putchar (' ');
11243 fputs (flags[cnt].str, stdout);
11244 first = false;
11245 val ^= flags[cnt].bit;
11248 if (val != 0 || first)
11250 if (! first)
11251 putchar (' ');
11252 print_vma (val, HEX);
11255 break;
11257 default:
11258 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11259 break;
11261 putchar ('\n');
11264 /* VMS vs Unix time offset and factor. */
11266 #define VMS_EPOCH_OFFSET 35067168000000000LL
11267 #define VMS_GRANULARITY_FACTOR 10000000
11268 #ifndef INT64_MIN
11269 #define INT64_MIN (-9223372036854775807LL - 1)
11270 #endif
11272 /* Display a VMS time in a human readable format. */
11274 static void
11275 print_vms_time (int64_t vmstime)
11277 struct tm *tm = NULL;
11278 time_t unxtime;
11280 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
11282 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
11283 unxtime = vmstime;
11284 if (unxtime == vmstime)
11285 tm = gmtime (&unxtime);
11287 if (tm != NULL)
11288 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
11289 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
11290 tm->tm_hour, tm->tm_min, tm->tm_sec);
11293 static void
11294 dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
11296 switch (entry->d_tag)
11298 case DT_IA_64_PLT_RESERVE:
11299 /* First 3 slots reserved. */
11300 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11301 printf (" -- ");
11302 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
11303 break;
11305 case DT_IA_64_VMS_LINKTIME:
11306 print_vms_time (entry->d_un.d_val);
11307 break;
11309 case DT_IA_64_VMS_LNKFLAGS:
11310 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11311 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
11312 printf (" CALL_DEBUG");
11313 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
11314 printf (" NOP0BUFS");
11315 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
11316 printf (" P0IMAGE");
11317 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
11318 printf (" MKTHREADS");
11319 if (entry->d_un.d_val & VMS_LF_UPCALLS)
11320 printf (" UPCALLS");
11321 if (entry->d_un.d_val & VMS_LF_IMGSTA)
11322 printf (" IMGSTA");
11323 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
11324 printf (" INITIALIZE");
11325 if (entry->d_un.d_val & VMS_LF_MAIN)
11326 printf (" MAIN");
11327 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
11328 printf (" EXE_INIT");
11329 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
11330 printf (" TBK_IN_IMG");
11331 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
11332 printf (" DBG_IN_IMG");
11333 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
11334 printf (" TBK_IN_DSF");
11335 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
11336 printf (" DBG_IN_DSF");
11337 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
11338 printf (" SIGNATURES");
11339 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
11340 printf (" REL_SEG_OFF");
11341 break;
11343 default:
11344 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11345 break;
11347 putchar ('\n');
11350 static bool
11351 get_32bit_dynamic_section (Filedata * filedata)
11353 Elf32_External_Dyn * edyn;
11354 Elf32_External_Dyn * ext;
11355 Elf_Internal_Dyn * entry;
11357 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
11358 filedata->dynamic_addr, 1,
11359 filedata->dynamic_size,
11360 _("dynamic section"));
11361 if (!edyn)
11362 return false;
11364 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11365 might not have the luxury of section headers. Look for the DT_NULL
11366 terminator to determine the number of entries. */
11367 for (ext = edyn, filedata->dynamic_nent = 0;
11368 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
11369 ext++)
11371 filedata->dynamic_nent++;
11372 if (BYTE_GET (ext->d_tag) == DT_NULL)
11373 break;
11376 filedata->dynamic_section
11377 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11378 if (filedata->dynamic_section == NULL)
11380 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11381 filedata->dynamic_nent);
11382 free (edyn);
11383 return false;
11386 for (ext = edyn, entry = filedata->dynamic_section;
11387 entry < filedata->dynamic_section + filedata->dynamic_nent;
11388 ext++, entry++)
11390 entry->d_tag = BYTE_GET (ext->d_tag);
11391 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
11394 free (edyn);
11396 return true;
11399 static bool
11400 get_64bit_dynamic_section (Filedata * filedata)
11402 Elf64_External_Dyn * edyn;
11403 Elf64_External_Dyn * ext;
11404 Elf_Internal_Dyn * entry;
11406 /* Read in the data. */
11407 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
11408 filedata->dynamic_addr, 1,
11409 filedata->dynamic_size,
11410 _("dynamic section"));
11411 if (!edyn)
11412 return false;
11414 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11415 might not have the luxury of section headers. Look for the DT_NULL
11416 terminator to determine the number of entries. */
11417 for (ext = edyn, filedata->dynamic_nent = 0;
11418 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
11419 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
11420 ext++)
11422 filedata->dynamic_nent++;
11423 if (BYTE_GET (ext->d_tag) == DT_NULL)
11424 break;
11427 filedata->dynamic_section
11428 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11429 if (filedata->dynamic_section == NULL)
11431 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11432 filedata->dynamic_nent);
11433 free (edyn);
11434 return false;
11437 /* Convert from external to internal formats. */
11438 for (ext = edyn, entry = filedata->dynamic_section;
11439 entry < filedata->dynamic_section + filedata->dynamic_nent;
11440 ext++, entry++)
11442 entry->d_tag = BYTE_GET (ext->d_tag);
11443 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
11446 free (edyn);
11448 return true;
11451 static bool
11452 get_dynamic_section (Filedata *filedata)
11454 if (filedata->dynamic_section)
11455 return true;
11457 if (is_32bit_elf)
11458 return get_32bit_dynamic_section (filedata);
11459 else
11460 return get_64bit_dynamic_section (filedata);
11463 static void
11464 print_dynamic_flags (uint64_t flags)
11466 bool first = true;
11468 while (flags)
11470 uint64_t flag;
11472 flag = flags & - flags;
11473 flags &= ~ flag;
11475 if (first)
11476 first = false;
11477 else
11478 putc (' ', stdout);
11480 switch (flag)
11482 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
11483 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
11484 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
11485 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
11486 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
11487 default: fputs (_("unknown"), stdout); break;
11490 puts ("");
11493 static uint64_t *
11494 get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
11496 unsigned char * e_data;
11497 uint64_t * i_data;
11499 /* If size_t is smaller than uint64_t, eg because you are building
11500 on a 32-bit host, then make sure that when number is cast to
11501 size_t no information is lost. */
11502 if ((size_t) number != number
11503 || ent_size * number / ent_size != number)
11505 error (_("Size overflow prevents reading %" PRIu64
11506 " elements of size %u\n"),
11507 number, ent_size);
11508 return NULL;
11511 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
11512 attempting to allocate memory when the read is bound to fail. */
11513 if (ent_size * number > filedata->file_size)
11515 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
11516 number);
11517 return NULL;
11520 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
11521 if (e_data == NULL)
11523 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
11524 number);
11525 return NULL;
11528 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
11530 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
11531 number * ent_size);
11532 free (e_data);
11533 return NULL;
11536 i_data = (uint64_t *) cmalloc ((size_t) number, sizeof (*i_data));
11537 if (i_data == NULL)
11539 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11540 number);
11541 free (e_data);
11542 return NULL;
11545 while (number--)
11546 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
11548 free (e_data);
11550 return i_data;
11553 static uint64_t
11554 get_num_dynamic_syms (Filedata * filedata)
11556 uint64_t num_of_syms = 0;
11558 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
11559 return num_of_syms;
11561 if (filedata->dynamic_info[DT_HASH])
11563 unsigned char nb[8];
11564 unsigned char nc[8];
11565 unsigned int hash_ent_size = 4;
11567 if ((filedata->file_header.e_machine == EM_ALPHA
11568 || filedata->file_header.e_machine == EM_S390
11569 || filedata->file_header.e_machine == EM_S390_OLD)
11570 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
11571 hash_ent_size = 8;
11573 if (fseek64 (filedata->handle,
11574 (filedata->archive_file_offset
11575 + offset_from_vma (filedata,
11576 filedata->dynamic_info[DT_HASH],
11577 sizeof nb + sizeof nc)),
11578 SEEK_SET))
11580 error (_("Unable to seek to start of dynamic information\n"));
11581 goto no_hash;
11584 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
11586 error (_("Failed to read in number of buckets\n"));
11587 goto no_hash;
11590 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
11592 error (_("Failed to read in number of chains\n"));
11593 goto no_hash;
11596 filedata->nbuckets = byte_get (nb, hash_ent_size);
11597 filedata->nchains = byte_get (nc, hash_ent_size);
11599 if (filedata->nbuckets != 0 && filedata->nchains != 0)
11601 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
11602 hash_ent_size);
11603 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
11604 hash_ent_size);
11606 if (filedata->buckets != NULL && filedata->chains != NULL)
11607 num_of_syms = filedata->nchains;
11609 no_hash:
11610 if (num_of_syms == 0)
11612 free (filedata->buckets);
11613 filedata->buckets = NULL;
11614 free (filedata->chains);
11615 filedata->chains = NULL;
11616 filedata->nbuckets = 0;
11620 if (filedata->dynamic_info_DT_GNU_HASH)
11622 unsigned char nb[16];
11623 uint64_t i, maxchain = 0xffffffff, bitmaskwords;
11624 uint64_t buckets_vma;
11625 uint64_t hn;
11627 if (fseek64 (filedata->handle,
11628 (filedata->archive_file_offset
11629 + offset_from_vma (filedata,
11630 filedata->dynamic_info_DT_GNU_HASH,
11631 sizeof nb)),
11632 SEEK_SET))
11634 error (_("Unable to seek to start of dynamic information\n"));
11635 goto no_gnu_hash;
11638 if (fread (nb, 16, 1, filedata->handle) != 1)
11640 error (_("Failed to read in number of buckets\n"));
11641 goto no_gnu_hash;
11644 filedata->ngnubuckets = byte_get (nb, 4);
11645 filedata->gnusymidx = byte_get (nb + 4, 4);
11646 bitmaskwords = byte_get (nb + 8, 4);
11647 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
11648 if (is_32bit_elf)
11649 buckets_vma += bitmaskwords * 4;
11650 else
11651 buckets_vma += bitmaskwords * 8;
11653 if (fseek64 (filedata->handle,
11654 (filedata->archive_file_offset
11655 + offset_from_vma (filedata, buckets_vma, 4)),
11656 SEEK_SET))
11658 error (_("Unable to seek to start of dynamic information\n"));
11659 goto no_gnu_hash;
11662 filedata->gnubuckets
11663 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
11665 if (filedata->gnubuckets == NULL)
11666 goto no_gnu_hash;
11668 for (i = 0; i < filedata->ngnubuckets; i++)
11669 if (filedata->gnubuckets[i] != 0)
11671 if (filedata->gnubuckets[i] < filedata->gnusymidx)
11672 goto no_gnu_hash;
11674 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11675 maxchain = filedata->gnubuckets[i];
11678 if (maxchain == 0xffffffff)
11679 goto no_gnu_hash;
11681 maxchain -= filedata->gnusymidx;
11683 if (fseek64 (filedata->handle,
11684 (filedata->archive_file_offset
11685 + offset_from_vma (filedata,
11686 buckets_vma + 4 * (filedata->ngnubuckets
11687 + maxchain),
11688 4)),
11689 SEEK_SET))
11691 error (_("Unable to seek to start of dynamic information\n"));
11692 goto no_gnu_hash;
11697 if (fread (nb, 4, 1, filedata->handle) != 1)
11699 error (_("Failed to determine last chain length\n"));
11700 goto no_gnu_hash;
11703 if (maxchain + 1 == 0)
11704 goto no_gnu_hash;
11706 ++maxchain;
11708 while ((byte_get (nb, 4) & 1) == 0);
11710 if (fseek64 (filedata->handle,
11711 (filedata->archive_file_offset
11712 + offset_from_vma (filedata, (buckets_vma
11713 + 4 * filedata->ngnubuckets),
11714 4)),
11715 SEEK_SET))
11717 error (_("Unable to seek to start of dynamic information\n"));
11718 goto no_gnu_hash;
11721 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11722 filedata->ngnuchains = maxchain;
11724 if (filedata->gnuchains == NULL)
11725 goto no_gnu_hash;
11727 if (filedata->dynamic_info_DT_MIPS_XHASH)
11729 if (fseek64 (filedata->handle,
11730 (filedata->archive_file_offset
11731 + offset_from_vma (filedata, (buckets_vma
11732 + 4 * (filedata->ngnubuckets
11733 + maxchain)), 4)),
11734 SEEK_SET))
11736 error (_("Unable to seek to start of dynamic information\n"));
11737 goto no_gnu_hash;
11740 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
11741 if (filedata->mipsxlat == NULL)
11742 goto no_gnu_hash;
11745 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11746 if (filedata->gnubuckets[hn] != 0)
11748 uint64_t si = filedata->gnubuckets[hn];
11749 uint64_t off = si - filedata->gnusymidx;
11753 if (filedata->dynamic_info_DT_MIPS_XHASH)
11755 if (off < filedata->ngnuchains
11756 && filedata->mipsxlat[off] >= num_of_syms)
11757 num_of_syms = filedata->mipsxlat[off] + 1;
11759 else
11761 if (si >= num_of_syms)
11762 num_of_syms = si + 1;
11764 si++;
11766 while (off < filedata->ngnuchains
11767 && (filedata->gnuchains[off++] & 1) == 0);
11770 if (num_of_syms == 0)
11772 no_gnu_hash:
11773 free (filedata->mipsxlat);
11774 filedata->mipsxlat = NULL;
11775 free (filedata->gnuchains);
11776 filedata->gnuchains = NULL;
11777 free (filedata->gnubuckets);
11778 filedata->gnubuckets = NULL;
11779 filedata->ngnubuckets = 0;
11780 filedata->ngnuchains = 0;
11784 return num_of_syms;
11787 /* Parse and display the contents of the dynamic section. */
11789 static bool
11790 process_dynamic_section (Filedata * filedata)
11792 Elf_Internal_Dyn * entry;
11794 if (filedata->dynamic_size <= 1)
11796 if (do_dynamic)
11798 if (filedata->is_separate)
11799 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11800 filedata->file_name);
11801 else
11802 printf (_("\nThere is no dynamic section in this file.\n"));
11805 return true;
11808 if (!get_dynamic_section (filedata))
11809 return false;
11811 /* Find the appropriate symbol table. */
11812 if (filedata->dynamic_symbols == NULL || do_histogram)
11814 uint64_t num_of_syms;
11816 for (entry = filedata->dynamic_section;
11817 entry < filedata->dynamic_section + filedata->dynamic_nent;
11818 ++entry)
11819 if (entry->d_tag == DT_SYMTAB)
11820 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
11821 else if (entry->d_tag == DT_SYMENT)
11822 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
11823 else if (entry->d_tag == DT_HASH)
11824 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
11825 else if (entry->d_tag == DT_GNU_HASH)
11826 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
11827 else if ((filedata->file_header.e_machine == EM_MIPS
11828 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11829 && entry->d_tag == DT_MIPS_XHASH)
11831 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11832 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
11835 num_of_syms = get_num_dynamic_syms (filedata);
11837 if (num_of_syms != 0
11838 && filedata->dynamic_symbols == NULL
11839 && filedata->dynamic_info[DT_SYMTAB]
11840 && filedata->dynamic_info[DT_SYMENT])
11842 Elf_Internal_Phdr *seg;
11843 uint64_t vma = filedata->dynamic_info[DT_SYMTAB];
11845 if (! get_program_headers (filedata))
11847 error (_("Cannot interpret virtual addresses "
11848 "without program headers.\n"));
11849 return false;
11852 for (seg = filedata->program_headers;
11853 seg < filedata->program_headers + filedata->file_header.e_phnum;
11854 ++seg)
11856 if (seg->p_type != PT_LOAD)
11857 continue;
11859 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11861 /* See PR 21379 for a reproducer. */
11862 error (_("Invalid PT_LOAD entry\n"));
11863 return false;
11866 if (vma >= (seg->p_vaddr & -seg->p_align)
11867 && vma < seg->p_vaddr + seg->p_filesz)
11869 /* Since we do not know how big the symbol table is,
11870 we default to reading in up to the end of PT_LOAD
11871 segment and processing that. This is overkill, I
11872 know, but it should work. */
11873 Elf_Internal_Shdr section;
11874 section.sh_offset = (vma - seg->p_vaddr
11875 + seg->p_offset);
11876 section.sh_size = (num_of_syms
11877 * filedata->dynamic_info[DT_SYMENT]);
11878 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
11880 if (do_checks
11881 && filedata->dynamic_symtab_section != NULL
11882 && ((filedata->dynamic_symtab_section->sh_offset
11883 != section.sh_offset)
11884 || (filedata->dynamic_symtab_section->sh_size
11885 != section.sh_size)
11886 || (filedata->dynamic_symtab_section->sh_entsize
11887 != section.sh_entsize)))
11888 warn (_("\
11889 the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11891 section.sh_name = filedata->string_table_length;
11892 filedata->dynamic_symbols
11893 = get_elf_symbols (filedata, &section,
11894 &filedata->num_dynamic_syms);
11895 if (filedata->dynamic_symbols == NULL
11896 || filedata->num_dynamic_syms != num_of_syms)
11898 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
11899 return false;
11901 break;
11907 /* Similarly find a string table. */
11908 if (filedata->dynamic_strings == NULL)
11909 for (entry = filedata->dynamic_section;
11910 entry < filedata->dynamic_section + filedata->dynamic_nent;
11911 ++entry)
11913 if (entry->d_tag == DT_STRTAB)
11914 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
11916 if (entry->d_tag == DT_STRSZ)
11917 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
11919 if (filedata->dynamic_info[DT_STRTAB]
11920 && filedata->dynamic_info[DT_STRSZ])
11922 uint64_t offset;
11923 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
11925 offset = offset_from_vma (filedata,
11926 filedata->dynamic_info[DT_STRTAB],
11927 str_tab_len);
11928 if (do_checks
11929 && filedata->dynamic_strtab_section
11930 && ((filedata->dynamic_strtab_section->sh_offset
11931 != (file_ptr) offset)
11932 || (filedata->dynamic_strtab_section->sh_size
11933 != str_tab_len)))
11934 warn (_("\
11935 the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11937 filedata->dynamic_strings
11938 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11939 _("dynamic string table"));
11940 if (filedata->dynamic_strings == NULL)
11942 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11943 break;
11946 filedata->dynamic_strings_length = str_tab_len;
11947 break;
11951 /* And find the syminfo section if available. */
11952 if (filedata->dynamic_syminfo == NULL)
11954 uint64_t syminsz = 0;
11956 for (entry = filedata->dynamic_section;
11957 entry < filedata->dynamic_section + filedata->dynamic_nent;
11958 ++entry)
11960 if (entry->d_tag == DT_SYMINENT)
11962 /* Note: these braces are necessary to avoid a syntax
11963 error from the SunOS4 C compiler. */
11964 /* PR binutils/17531: A corrupt file can trigger this test.
11965 So do not use an assert, instead generate an error message. */
11966 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
11967 error (_("Bad value (%d) for SYMINENT entry\n"),
11968 (int) entry->d_un.d_val);
11970 else if (entry->d_tag == DT_SYMINSZ)
11971 syminsz = entry->d_un.d_val;
11972 else if (entry->d_tag == DT_SYMINFO)
11973 filedata->dynamic_syminfo_offset
11974 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
11977 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
11979 Elf_External_Syminfo * extsyminfo;
11980 Elf_External_Syminfo * extsym;
11981 Elf_Internal_Syminfo * syminfo;
11983 /* There is a syminfo section. Read the data. */
11984 extsyminfo = (Elf_External_Syminfo *)
11985 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11986 1, syminsz, _("symbol information"));
11987 if (!extsyminfo)
11988 return false;
11990 if (filedata->dynamic_syminfo != NULL)
11992 error (_("Multiple dynamic symbol information sections found\n"));
11993 free (filedata->dynamic_syminfo);
11995 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11996 if (filedata->dynamic_syminfo == NULL)
11998 error (_("Out of memory allocating %" PRIu64
11999 " bytes for dynamic symbol info\n"),
12000 syminsz);
12001 return false;
12004 filedata->dynamic_syminfo_nent
12005 = syminsz / sizeof (Elf_External_Syminfo);
12006 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
12007 syminfo < (filedata->dynamic_syminfo
12008 + filedata->dynamic_syminfo_nent);
12009 ++syminfo, ++extsym)
12011 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
12012 syminfo->si_flags = BYTE_GET (extsym->si_flags);
12015 free (extsyminfo);
12019 if (do_dynamic && filedata->dynamic_addr)
12021 if (filedata->is_separate)
12022 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
12023 "\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
12024 filedata->dynamic_nent),
12025 filedata->file_name,
12026 filedata->dynamic_addr,
12027 filedata->dynamic_nent);
12028 else
12029 printf (ngettext ("\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
12030 "\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
12031 filedata->dynamic_nent),
12032 filedata->dynamic_addr,
12033 filedata->dynamic_nent);
12035 if (do_dynamic)
12036 printf (_(" Tag Type Name/Value\n"));
12038 for (entry = filedata->dynamic_section;
12039 entry < filedata->dynamic_section + filedata->dynamic_nent;
12040 entry++)
12042 if (do_dynamic)
12044 const char * dtype;
12046 putchar (' ');
12047 print_vma (entry->d_tag, FULL_HEX);
12048 dtype = get_dynamic_type (filedata, entry->d_tag);
12049 printf (" (%s)%*s", dtype,
12050 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
12053 switch (entry->d_tag)
12055 case DT_FLAGS:
12056 if (do_dynamic)
12057 print_dynamic_flags (entry->d_un.d_val);
12058 break;
12060 case DT_AUXILIARY:
12061 case DT_FILTER:
12062 case DT_CONFIG:
12063 case DT_DEPAUDIT:
12064 case DT_AUDIT:
12065 if (do_dynamic)
12067 switch (entry->d_tag)
12069 case DT_AUXILIARY:
12070 printf (_("Auxiliary library"));
12071 break;
12073 case DT_FILTER:
12074 printf (_("Filter library"));
12075 break;
12077 case DT_CONFIG:
12078 printf (_("Configuration file"));
12079 break;
12081 case DT_DEPAUDIT:
12082 printf (_("Dependency audit library"));
12083 break;
12085 case DT_AUDIT:
12086 printf (_("Audit library"));
12087 break;
12090 if (valid_dynamic_name (filedata, entry->d_un.d_val))
12091 printf (": [%s]\n",
12092 get_dynamic_name (filedata, entry->d_un.d_val));
12093 else
12095 printf (": ");
12096 print_vma (entry->d_un.d_val, PREFIX_HEX);
12097 putchar ('\n');
12100 break;
12102 case DT_FEATURE:
12103 if (do_dynamic)
12105 printf (_("Flags:"));
12107 if (entry->d_un.d_val == 0)
12108 printf (_(" None\n"));
12109 else
12111 uint64_t val = entry->d_un.d_val;
12113 if (val & DTF_1_PARINIT)
12115 printf (" PARINIT");
12116 val ^= DTF_1_PARINIT;
12118 if (val & DTF_1_CONFEXP)
12120 printf (" CONFEXP");
12121 val ^= DTF_1_CONFEXP;
12123 if (val != 0)
12124 printf (" %" PRIx64, val);
12125 puts ("");
12128 break;
12130 case DT_POSFLAG_1:
12131 if (do_dynamic)
12133 printf (_("Flags:"));
12135 if (entry->d_un.d_val == 0)
12136 printf (_(" None\n"));
12137 else
12139 uint64_t val = entry->d_un.d_val;
12141 if (val & DF_P1_LAZYLOAD)
12143 printf (" LAZYLOAD");
12144 val ^= DF_P1_LAZYLOAD;
12146 if (val & DF_P1_GROUPPERM)
12148 printf (" GROUPPERM");
12149 val ^= DF_P1_GROUPPERM;
12151 if (val != 0)
12152 printf (" %" PRIx64, val);
12153 puts ("");
12156 break;
12158 case DT_FLAGS_1:
12159 if (do_dynamic)
12161 printf (_("Flags:"));
12162 if (entry->d_un.d_val == 0)
12163 printf (_(" None\n"));
12164 else
12166 uint64_t val = entry->d_un.d_val;
12168 if (val & DF_1_NOW)
12170 printf (" NOW");
12171 val ^= DF_1_NOW;
12173 if (val & DF_1_GLOBAL)
12175 printf (" GLOBAL");
12176 val ^= DF_1_GLOBAL;
12178 if (val & DF_1_GROUP)
12180 printf (" GROUP");
12181 val ^= DF_1_GROUP;
12183 if (val & DF_1_NODELETE)
12185 printf (" NODELETE");
12186 val ^= DF_1_NODELETE;
12188 if (val & DF_1_LOADFLTR)
12190 printf (" LOADFLTR");
12191 val ^= DF_1_LOADFLTR;
12193 if (val & DF_1_INITFIRST)
12195 printf (" INITFIRST");
12196 val ^= DF_1_INITFIRST;
12198 if (val & DF_1_NOOPEN)
12200 printf (" NOOPEN");
12201 val ^= DF_1_NOOPEN;
12203 if (val & DF_1_ORIGIN)
12205 printf (" ORIGIN");
12206 val ^= DF_1_ORIGIN;
12208 if (val & DF_1_DIRECT)
12210 printf (" DIRECT");
12211 val ^= DF_1_DIRECT;
12213 if (val & DF_1_TRANS)
12215 printf (" TRANS");
12216 val ^= DF_1_TRANS;
12218 if (val & DF_1_INTERPOSE)
12220 printf (" INTERPOSE");
12221 val ^= DF_1_INTERPOSE;
12223 if (val & DF_1_NODEFLIB)
12225 printf (" NODEFLIB");
12226 val ^= DF_1_NODEFLIB;
12228 if (val & DF_1_NODUMP)
12230 printf (" NODUMP");
12231 val ^= DF_1_NODUMP;
12233 if (val & DF_1_CONFALT)
12235 printf (" CONFALT");
12236 val ^= DF_1_CONFALT;
12238 if (val & DF_1_ENDFILTEE)
12240 printf (" ENDFILTEE");
12241 val ^= DF_1_ENDFILTEE;
12243 if (val & DF_1_DISPRELDNE)
12245 printf (" DISPRELDNE");
12246 val ^= DF_1_DISPRELDNE;
12248 if (val & DF_1_DISPRELPND)
12250 printf (" DISPRELPND");
12251 val ^= DF_1_DISPRELPND;
12253 if (val & DF_1_NODIRECT)
12255 printf (" NODIRECT");
12256 val ^= DF_1_NODIRECT;
12258 if (val & DF_1_IGNMULDEF)
12260 printf (" IGNMULDEF");
12261 val ^= DF_1_IGNMULDEF;
12263 if (val & DF_1_NOKSYMS)
12265 printf (" NOKSYMS");
12266 val ^= DF_1_NOKSYMS;
12268 if (val & DF_1_NOHDR)
12270 printf (" NOHDR");
12271 val ^= DF_1_NOHDR;
12273 if (val & DF_1_EDITED)
12275 printf (" EDITED");
12276 val ^= DF_1_EDITED;
12278 if (val & DF_1_NORELOC)
12280 printf (" NORELOC");
12281 val ^= DF_1_NORELOC;
12283 if (val & DF_1_SYMINTPOSE)
12285 printf (" SYMINTPOSE");
12286 val ^= DF_1_SYMINTPOSE;
12288 if (val & DF_1_GLOBAUDIT)
12290 printf (" GLOBAUDIT");
12291 val ^= DF_1_GLOBAUDIT;
12293 if (val & DF_1_SINGLETON)
12295 printf (" SINGLETON");
12296 val ^= DF_1_SINGLETON;
12298 if (val & DF_1_STUB)
12300 printf (" STUB");
12301 val ^= DF_1_STUB;
12303 if (val & DF_1_PIE)
12305 printf (" PIE");
12306 val ^= DF_1_PIE;
12308 if (val & DF_1_KMOD)
12310 printf (" KMOD");
12311 val ^= DF_1_KMOD;
12313 if (val & DF_1_WEAKFILTER)
12315 printf (" WEAKFILTER");
12316 val ^= DF_1_WEAKFILTER;
12318 if (val & DF_1_NOCOMMON)
12320 printf (" NOCOMMON");
12321 val ^= DF_1_NOCOMMON;
12323 if (val != 0)
12324 printf (" %" PRIx64, val);
12325 puts ("");
12328 break;
12330 case DT_PLTREL:
12331 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
12332 if (do_dynamic)
12333 puts (get_dynamic_type (filedata, entry->d_un.d_val));
12334 break;
12336 case DT_NULL :
12337 case DT_NEEDED :
12338 case DT_PLTGOT :
12339 case DT_HASH :
12340 case DT_STRTAB :
12341 case DT_SYMTAB :
12342 case DT_RELA :
12343 case DT_INIT :
12344 case DT_FINI :
12345 case DT_SONAME :
12346 case DT_RPATH :
12347 case DT_SYMBOLIC:
12348 case DT_REL :
12349 case DT_RELR :
12350 case DT_DEBUG :
12351 case DT_TEXTREL :
12352 case DT_JMPREL :
12353 case DT_RUNPATH :
12354 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
12356 if (do_dynamic)
12358 const char *name;
12360 if (valid_dynamic_name (filedata, entry->d_un.d_val))
12361 name = get_dynamic_name (filedata, entry->d_un.d_val);
12362 else
12363 name = NULL;
12365 if (name)
12367 switch (entry->d_tag)
12369 case DT_NEEDED:
12370 printf (_("Shared library: [%s]"), name);
12372 if (filedata->program_interpreter
12373 && streq (name, filedata->program_interpreter))
12374 printf (_(" program interpreter"));
12375 break;
12377 case DT_SONAME:
12378 printf (_("Library soname: [%s]"), name);
12379 break;
12381 case DT_RPATH:
12382 printf (_("Library rpath: [%s]"), name);
12383 break;
12385 case DT_RUNPATH:
12386 printf (_("Library runpath: [%s]"), name);
12387 break;
12389 default:
12390 print_vma (entry->d_un.d_val, PREFIX_HEX);
12391 break;
12394 else
12395 print_vma (entry->d_un.d_val, PREFIX_HEX);
12397 putchar ('\n');
12399 break;
12401 case DT_PLTRELSZ:
12402 case DT_RELASZ :
12403 case DT_STRSZ :
12404 case DT_RELSZ :
12405 case DT_RELAENT :
12406 case DT_RELRENT :
12407 case DT_RELRSZ :
12408 case DT_SYMENT :
12409 case DT_RELENT :
12410 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
12411 /* Fall through. */
12412 case DT_PLTPADSZ:
12413 case DT_MOVEENT :
12414 case DT_MOVESZ :
12415 case DT_PREINIT_ARRAYSZ:
12416 case DT_INIT_ARRAYSZ:
12417 case DT_FINI_ARRAYSZ:
12418 case DT_GNU_CONFLICTSZ:
12419 case DT_GNU_LIBLISTSZ:
12420 if (do_dynamic)
12422 print_vma (entry->d_un.d_val, UNSIGNED);
12423 printf (_(" (bytes)\n"));
12425 break;
12427 case DT_VERDEFNUM:
12428 case DT_VERNEEDNUM:
12429 case DT_RELACOUNT:
12430 case DT_RELCOUNT:
12431 if (do_dynamic)
12433 print_vma (entry->d_un.d_val, UNSIGNED);
12434 putchar ('\n');
12436 break;
12438 case DT_SYMINSZ:
12439 case DT_SYMINENT:
12440 case DT_SYMINFO:
12441 case DT_USED:
12442 case DT_INIT_ARRAY:
12443 case DT_FINI_ARRAY:
12444 if (do_dynamic)
12446 if (entry->d_tag == DT_USED
12447 && valid_dynamic_name (filedata, entry->d_un.d_val))
12449 const char *name
12450 = get_dynamic_name (filedata, entry->d_un.d_val);
12452 if (*name)
12454 printf (_("Not needed object: [%s]\n"), name);
12455 break;
12459 print_vma (entry->d_un.d_val, PREFIX_HEX);
12460 putchar ('\n');
12462 break;
12464 case DT_BIND_NOW:
12465 /* The value of this entry is ignored. */
12466 if (do_dynamic)
12467 putchar ('\n');
12468 break;
12470 case DT_GNU_PRELINKED:
12471 if (do_dynamic)
12473 struct tm * tmp;
12474 time_t atime = entry->d_un.d_val;
12476 tmp = gmtime (&atime);
12477 /* PR 17533 file: 041-1244816-0.004. */
12478 if (tmp == NULL)
12479 printf (_("<corrupt time val: %" PRIx64),
12480 (uint64_t) atime);
12481 else
12482 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
12483 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12484 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
12487 break;
12489 case DT_GNU_HASH:
12490 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
12491 if (do_dynamic)
12493 print_vma (entry->d_un.d_val, PREFIX_HEX);
12494 putchar ('\n');
12496 break;
12498 case DT_GNU_FLAGS_1:
12499 if (do_dynamic)
12501 printf (_("Flags:"));
12502 if (entry->d_un.d_val == 0)
12503 printf (_(" None\n"));
12504 else
12506 uint64_t val = entry->d_un.d_val;
12508 if (val & DF_GNU_1_UNIQUE)
12510 printf (" UNIQUE");
12511 val ^= DF_GNU_1_UNIQUE;
12513 if (val != 0)
12514 printf (" %" PRIx64, val);
12515 puts ("");
12518 break;
12520 default:
12521 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
12522 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
12523 = entry->d_un.d_val;
12525 if (do_dynamic)
12527 switch (filedata->file_header.e_machine)
12529 case EM_AARCH64:
12530 dynamic_section_aarch64_val (entry);
12531 break;
12532 case EM_MIPS:
12533 case EM_MIPS_RS3_LE:
12534 dynamic_section_mips_val (filedata, entry);
12535 break;
12536 case EM_PARISC:
12537 dynamic_section_parisc_val (entry);
12538 break;
12539 case EM_IA_64:
12540 dynamic_section_ia64_val (entry);
12541 break;
12542 default:
12543 print_vma (entry->d_un.d_val, PREFIX_HEX);
12544 putchar ('\n');
12547 break;
12551 return true;
12554 static char *
12555 get_ver_flags (unsigned int flags)
12557 static char buff[128];
12559 buff[0] = 0;
12561 if (flags == 0)
12562 return _("none");
12564 if (flags & VER_FLG_BASE)
12565 strcat (buff, "BASE");
12567 if (flags & VER_FLG_WEAK)
12569 if (flags & VER_FLG_BASE)
12570 strcat (buff, " | ");
12572 strcat (buff, "WEAK");
12575 if (flags & VER_FLG_INFO)
12577 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
12578 strcat (buff, " | ");
12580 strcat (buff, "INFO");
12583 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12585 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12586 strcat (buff, " | ");
12588 strcat (buff, _("<unknown>"));
12591 return buff;
12594 /* Display the contents of the version sections. */
12596 static bool
12597 process_version_sections (Filedata * filedata)
12599 Elf_Internal_Shdr * section;
12600 unsigned i;
12601 bool found = false;
12603 if (! do_version)
12604 return true;
12606 for (i = 0, section = filedata->section_headers;
12607 i < filedata->file_header.e_shnum;
12608 i++, section++)
12610 switch (section->sh_type)
12612 case SHT_GNU_verdef:
12614 Elf_External_Verdef * edefs;
12615 size_t idx;
12616 size_t cnt;
12617 char * endbuf;
12619 found = true;
12621 if (filedata->is_separate)
12622 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12623 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12624 section->sh_info),
12625 filedata->file_name,
12626 printable_section_name (filedata, section),
12627 section->sh_info);
12628 else
12629 printf (ngettext ("\nVersion definition section '%s' "
12630 "contains %u entry:\n",
12631 "\nVersion definition section '%s' "
12632 "contains %u entries:\n",
12633 section->sh_info),
12634 printable_section_name (filedata, section),
12635 section->sh_info);
12637 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
12638 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12639 section->sh_offset, section->sh_link,
12640 printable_section_name_from_index (filedata, section->sh_link, NULL));
12642 edefs = (Elf_External_Verdef *)
12643 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
12644 _("version definition section"));
12645 if (!edefs)
12646 break;
12647 endbuf = (char *) edefs + section->sh_size;
12649 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12651 char * vstart;
12652 Elf_External_Verdef * edef;
12653 Elf_Internal_Verdef ent;
12654 Elf_External_Verdaux * eaux;
12655 Elf_Internal_Verdaux aux;
12656 size_t isum;
12657 int j;
12659 vstart = ((char *) edefs) + idx;
12660 if (vstart + sizeof (*edef) > endbuf)
12661 break;
12663 edef = (Elf_External_Verdef *) vstart;
12665 ent.vd_version = BYTE_GET (edef->vd_version);
12666 ent.vd_flags = BYTE_GET (edef->vd_flags);
12667 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12668 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12669 ent.vd_hash = BYTE_GET (edef->vd_hash);
12670 ent.vd_aux = BYTE_GET (edef->vd_aux);
12671 ent.vd_next = BYTE_GET (edef->vd_next);
12673 printf (_(" %#06zx: Rev: %d Flags: %s"),
12674 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12676 printf (_(" Index: %d Cnt: %d "),
12677 ent.vd_ndx, ent.vd_cnt);
12679 /* Check for overflow. */
12680 if (ent.vd_aux > (size_t) (endbuf - vstart))
12681 break;
12683 vstart += ent.vd_aux;
12685 if (vstart + sizeof (*eaux) > endbuf)
12686 break;
12687 eaux = (Elf_External_Verdaux *) vstart;
12689 aux.vda_name = BYTE_GET (eaux->vda_name);
12690 aux.vda_next = BYTE_GET (eaux->vda_next);
12692 if (valid_dynamic_name (filedata, aux.vda_name))
12693 printf (_("Name: %s\n"),
12694 get_dynamic_name (filedata, aux.vda_name));
12695 else
12696 printf (_("Name index: %ld\n"), aux.vda_name);
12698 isum = idx + ent.vd_aux;
12700 for (j = 1; j < ent.vd_cnt; j++)
12702 if (aux.vda_next < sizeof (*eaux)
12703 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12705 warn (_("Invalid vda_next field of %lx\n"),
12706 aux.vda_next);
12707 j = ent.vd_cnt;
12708 break;
12710 /* Check for overflow. */
12711 if (aux.vda_next > (size_t) (endbuf - vstart))
12712 break;
12714 isum += aux.vda_next;
12715 vstart += aux.vda_next;
12717 if (vstart + sizeof (*eaux) > endbuf)
12718 break;
12719 eaux = (Elf_External_Verdaux *) vstart;
12721 aux.vda_name = BYTE_GET (eaux->vda_name);
12722 aux.vda_next = BYTE_GET (eaux->vda_next);
12724 if (valid_dynamic_name (filedata, aux.vda_name))
12725 printf (_(" %#06zx: Parent %d: %s\n"),
12726 isum, j,
12727 get_dynamic_name (filedata, aux.vda_name));
12728 else
12729 printf (_(" %#06zx: Parent %d, name index: %ld\n"),
12730 isum, j, aux.vda_name);
12733 if (j < ent.vd_cnt)
12734 printf (_(" Version def aux past end of section\n"));
12736 /* PR 17531:
12737 file: id:000001,src:000172+005151,op:splice,rep:2. */
12738 if (ent.vd_next < sizeof (*edef)
12739 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12741 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12742 cnt = section->sh_info;
12743 break;
12745 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
12746 break;
12748 idx += ent.vd_next;
12751 if (cnt < section->sh_info)
12752 printf (_(" Version definition past end of section\n"));
12754 free (edefs);
12756 break;
12758 case SHT_GNU_verneed:
12760 Elf_External_Verneed * eneed;
12761 size_t idx;
12762 size_t cnt;
12763 char * endbuf;
12765 found = true;
12767 if (filedata->is_separate)
12768 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12769 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12770 section->sh_info),
12771 filedata->file_name,
12772 printable_section_name (filedata, section),
12773 section->sh_info);
12774 else
12775 printf (ngettext ("\nVersion needs section '%s' "
12776 "contains %u entry:\n",
12777 "\nVersion needs section '%s' "
12778 "contains %u entries:\n",
12779 section->sh_info),
12780 printable_section_name (filedata, section),
12781 section->sh_info);
12783 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
12784 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12785 section->sh_offset, section->sh_link,
12786 printable_section_name_from_index (filedata, section->sh_link, NULL));
12788 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
12789 section->sh_offset, 1,
12790 section->sh_size,
12791 _("Version Needs section"));
12792 if (!eneed)
12793 break;
12794 endbuf = (char *) eneed + section->sh_size;
12796 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12798 Elf_External_Verneed * entry;
12799 Elf_Internal_Verneed ent;
12800 size_t isum;
12801 int j;
12802 char * vstart;
12804 vstart = ((char *) eneed) + idx;
12805 if (vstart + sizeof (*entry) > endbuf)
12806 break;
12808 entry = (Elf_External_Verneed *) vstart;
12810 ent.vn_version = BYTE_GET (entry->vn_version);
12811 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12812 ent.vn_file = BYTE_GET (entry->vn_file);
12813 ent.vn_aux = BYTE_GET (entry->vn_aux);
12814 ent.vn_next = BYTE_GET (entry->vn_next);
12816 printf (_(" %#06zx: Version: %d"), idx, ent.vn_version);
12818 if (valid_dynamic_name (filedata, ent.vn_file))
12819 printf (_(" File: %s"),
12820 get_dynamic_name (filedata, ent.vn_file));
12821 else
12822 printf (_(" File: %lx"), ent.vn_file);
12824 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12826 /* Check for overflow. */
12827 if (ent.vn_aux > (size_t) (endbuf - vstart))
12828 break;
12829 vstart += ent.vn_aux;
12831 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12833 Elf_External_Vernaux * eaux;
12834 Elf_Internal_Vernaux aux;
12836 if (vstart + sizeof (*eaux) > endbuf)
12837 break;
12838 eaux = (Elf_External_Vernaux *) vstart;
12840 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12841 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12842 aux.vna_other = BYTE_GET (eaux->vna_other);
12843 aux.vna_name = BYTE_GET (eaux->vna_name);
12844 aux.vna_next = BYTE_GET (eaux->vna_next);
12846 if (valid_dynamic_name (filedata, aux.vna_name))
12847 printf (_(" %#06zx: Name: %s"),
12848 isum, get_dynamic_name (filedata, aux.vna_name));
12849 else
12850 printf (_(" %#06zx: Name index: %lx"),
12851 isum, aux.vna_name);
12853 printf (_(" Flags: %s Version: %d\n"),
12854 get_ver_flags (aux.vna_flags), aux.vna_other);
12856 if (aux.vna_next < sizeof (*eaux)
12857 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
12859 warn (_("Invalid vna_next field of %lx\n"),
12860 aux.vna_next);
12861 j = ent.vn_cnt;
12862 break;
12864 /* Check for overflow. */
12865 if (aux.vna_next > (size_t) (endbuf - vstart))
12866 break;
12867 isum += aux.vna_next;
12868 vstart += aux.vna_next;
12871 if (j < ent.vn_cnt)
12872 warn (_("Missing Version Needs auxiliary information\n"));
12874 if (ent.vn_next < sizeof (*entry)
12875 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
12877 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
12878 cnt = section->sh_info;
12879 break;
12881 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12882 break;
12883 idx += ent.vn_next;
12886 if (cnt < section->sh_info)
12887 warn (_("Missing Version Needs information\n"));
12889 free (eneed);
12891 break;
12893 case SHT_GNU_versym:
12895 Elf_Internal_Shdr * link_section;
12896 uint64_t total;
12897 unsigned int cnt;
12898 unsigned char * edata;
12899 unsigned short * data;
12900 char * strtab;
12901 Elf_Internal_Sym * symbols;
12902 Elf_Internal_Shdr * string_sec;
12903 uint64_t num_syms;
12904 uint64_t off;
12906 if (section->sh_link >= filedata->file_header.e_shnum)
12907 break;
12909 link_section = filedata->section_headers + section->sh_link;
12910 total = section->sh_size / sizeof (Elf_External_Versym);
12912 if (link_section->sh_link >= filedata->file_header.e_shnum)
12913 break;
12915 found = true;
12917 symbols = get_elf_symbols (filedata, link_section, & num_syms);
12918 if (symbols == NULL)
12919 break;
12921 string_sec = filedata->section_headers + link_section->sh_link;
12923 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
12924 string_sec->sh_size,
12925 _("version string table"));
12926 if (!strtab)
12928 free (symbols);
12929 break;
12932 if (filedata->is_separate)
12933 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entry:\n",
12934 "\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entries:\n",
12935 total),
12936 filedata->file_name,
12937 printable_section_name (filedata, section),
12938 total);
12939 else
12940 printf (ngettext ("\nVersion symbols section '%s' "
12941 "contains %" PRIu64 " entry:\n",
12942 "\nVersion symbols section '%s' "
12943 "contains %" PRIu64 " entries:\n",
12944 total),
12945 printable_section_name (filedata, section),
12946 total);
12948 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
12949 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12950 section->sh_offset, section->sh_link,
12951 printable_section_name (filedata, link_section));
12953 off = offset_from_vma (filedata,
12954 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
12955 total * sizeof (short));
12956 edata = (unsigned char *) get_data (NULL, filedata, off,
12957 sizeof (short), total,
12958 _("version symbol data"));
12959 if (!edata)
12961 free (strtab);
12962 free (symbols);
12963 break;
12966 data = (short unsigned int *) cmalloc (total, sizeof (short));
12968 for (cnt = total; cnt --;)
12969 data[cnt] = byte_get (edata + cnt * sizeof (short),
12970 sizeof (short));
12972 free (edata);
12974 for (cnt = 0; cnt < total; cnt += 4)
12976 int j, nn;
12977 char *name;
12978 char *invalid = _("*invalid*");
12980 printf (" %03x:", cnt);
12982 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
12983 switch (data[cnt + j])
12985 case 0:
12986 fputs (_(" 0 (*local*) "), stdout);
12987 break;
12989 case 1:
12990 fputs (_(" 1 (*global*) "), stdout);
12991 break;
12993 default:
12994 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12995 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
12997 /* If this index value is greater than the size of the symbols
12998 array, break to avoid an out-of-bounds read. */
12999 if (cnt + j >= num_syms)
13001 warn (_("invalid index into symbol array\n"));
13002 break;
13005 name = NULL;
13006 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
13008 Elf_Internal_Verneed ivn;
13009 uint64_t offset;
13011 offset = offset_from_vma
13012 (filedata,
13013 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
13014 sizeof (Elf_External_Verneed));
13018 Elf_Internal_Vernaux ivna;
13019 Elf_External_Verneed evn;
13020 Elf_External_Vernaux evna;
13021 uint64_t a_off;
13023 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
13024 _("version need")) == NULL)
13025 break;
13027 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13028 ivn.vn_next = BYTE_GET (evn.vn_next);
13030 a_off = offset + ivn.vn_aux;
13034 if (get_data (&evna, filedata, a_off, sizeof (evna),
13035 1, _("version need aux (2)")) == NULL)
13037 ivna.vna_next = 0;
13038 ivna.vna_other = 0;
13040 else
13042 ivna.vna_next = BYTE_GET (evna.vna_next);
13043 ivna.vna_other = BYTE_GET (evna.vna_other);
13046 a_off += ivna.vna_next;
13048 while (ivna.vna_other != data[cnt + j]
13049 && ivna.vna_next != 0);
13051 if (ivna.vna_other == data[cnt + j])
13053 ivna.vna_name = BYTE_GET (evna.vna_name);
13055 if (ivna.vna_name >= string_sec->sh_size)
13056 name = invalid;
13057 else
13058 name = strtab + ivna.vna_name;
13059 break;
13062 offset += ivn.vn_next;
13064 while (ivn.vn_next);
13067 if (data[cnt + j] != 0x8001
13068 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
13070 Elf_Internal_Verdef ivd;
13071 Elf_External_Verdef evd;
13072 uint64_t offset;
13074 offset = offset_from_vma
13075 (filedata,
13076 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
13077 sizeof evd);
13081 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
13082 _("version def")) == NULL)
13084 ivd.vd_next = 0;
13085 /* PR 17531: file: 046-1082287-0.004. */
13086 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
13087 break;
13089 else
13091 ivd.vd_next = BYTE_GET (evd.vd_next);
13092 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13095 offset += ivd.vd_next;
13097 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
13098 && ivd.vd_next != 0);
13100 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
13102 Elf_External_Verdaux evda;
13103 Elf_Internal_Verdaux ivda;
13105 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13107 if (get_data (&evda, filedata,
13108 offset - ivd.vd_next + ivd.vd_aux,
13109 sizeof (evda), 1,
13110 _("version def aux")) == NULL)
13111 break;
13113 ivda.vda_name = BYTE_GET (evda.vda_name);
13115 if (ivda.vda_name >= string_sec->sh_size)
13116 name = invalid;
13117 else if (name != NULL && name != invalid)
13118 name = _("*both*");
13119 else
13120 name = strtab + ivda.vda_name;
13123 if (name != NULL)
13124 nn += printf ("(%s%-*s",
13125 name,
13126 12 - (int) strlen (name),
13127 ")");
13129 if (nn < 18)
13130 printf ("%*c", 18 - nn, ' ');
13133 putchar ('\n');
13136 free (data);
13137 free (strtab);
13138 free (symbols);
13140 break;
13142 default:
13143 break;
13147 if (! found)
13149 if (filedata->is_separate)
13150 printf (_("\nNo version information found in linked file '%s'.\n"),
13151 filedata->file_name);
13152 else
13153 printf (_("\nNo version information found in this file.\n"));
13156 return true;
13159 static const char *
13160 get_symbol_binding (Filedata * filedata, unsigned int binding)
13162 static char buff[64];
13164 switch (binding)
13166 case STB_LOCAL: return "LOCAL";
13167 case STB_GLOBAL: return "GLOBAL";
13168 case STB_WEAK: return "WEAK";
13169 default:
13170 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
13171 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
13172 binding);
13173 else if (binding >= STB_LOOS && binding <= STB_HIOS)
13175 if (binding == STB_GNU_UNIQUE
13176 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
13177 return "UNIQUE";
13178 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
13180 else
13181 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
13182 return buff;
13186 static const char *
13187 get_symbol_type (Filedata * filedata, unsigned int type)
13189 static char buff[64];
13191 switch (type)
13193 case STT_NOTYPE: return "NOTYPE";
13194 case STT_OBJECT: return "OBJECT";
13195 case STT_FUNC: return "FUNC";
13196 case STT_SECTION: return "SECTION";
13197 case STT_FILE: return "FILE";
13198 case STT_COMMON: return "COMMON";
13199 case STT_TLS: return "TLS";
13200 case STT_RELC: return "RELC";
13201 case STT_SRELC: return "SRELC";
13202 default:
13203 if (type >= STT_LOPROC && type <= STT_HIPROC)
13205 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
13206 return "THUMB_FUNC";
13208 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
13209 return "REGISTER";
13211 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
13212 return "PARISC_MILLI";
13214 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
13216 else if (type >= STT_LOOS && type <= STT_HIOS)
13218 if (filedata->file_header.e_machine == EM_PARISC)
13220 if (type == STT_HP_OPAQUE)
13221 return "HP_OPAQUE";
13222 if (type == STT_HP_STUB)
13223 return "HP_STUB";
13226 if (type == STT_GNU_IFUNC
13227 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
13228 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
13229 return "IFUNC";
13231 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
13233 else
13234 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
13235 return buff;
13239 static const char *
13240 get_symbol_visibility (unsigned int visibility)
13242 switch (visibility)
13244 case STV_DEFAULT: return "DEFAULT";
13245 case STV_INTERNAL: return "INTERNAL";
13246 case STV_HIDDEN: return "HIDDEN";
13247 case STV_PROTECTED: return "PROTECTED";
13248 default:
13249 error (_("Unrecognized visibility value: %u\n"), visibility);
13250 return _("<unknown>");
13254 static const char *
13255 get_alpha_symbol_other (unsigned int other)
13257 switch (other)
13259 case STO_ALPHA_NOPV: return "NOPV";
13260 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
13261 default:
13262 error (_("Unrecognized alpha specific other value: %u\n"), other);
13263 return _("<unknown>");
13267 static const char *
13268 get_solaris_symbol_visibility (unsigned int visibility)
13270 switch (visibility)
13272 case 4: return "EXPORTED";
13273 case 5: return "SINGLETON";
13274 case 6: return "ELIMINATE";
13275 default: return get_symbol_visibility (visibility);
13279 static const char *
13280 get_aarch64_symbol_other (unsigned int other)
13282 static char buf[32];
13284 if (other & STO_AARCH64_VARIANT_PCS)
13286 other &= ~STO_AARCH64_VARIANT_PCS;
13287 if (other == 0)
13288 return "VARIANT_PCS";
13289 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
13290 return buf;
13292 return NULL;
13295 static const char *
13296 get_mips_symbol_other (unsigned int other)
13298 switch (other)
13300 case STO_OPTIONAL: return "OPTIONAL";
13301 case STO_MIPS_PLT: return "MIPS PLT";
13302 case STO_MIPS_PIC: return "MIPS PIC";
13303 case STO_MICROMIPS: return "MICROMIPS";
13304 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
13305 case STO_MIPS16: return "MIPS16";
13306 default: return NULL;
13310 static const char *
13311 get_ia64_symbol_other (Filedata * filedata, unsigned int other)
13313 if (is_ia64_vms (filedata))
13315 static char res[32];
13317 res[0] = 0;
13319 /* Function types is for images and .STB files only. */
13320 switch (filedata->file_header.e_type)
13322 case ET_DYN:
13323 case ET_EXEC:
13324 switch (VMS_ST_FUNC_TYPE (other))
13326 case VMS_SFT_CODE_ADDR:
13327 strcat (res, " CA");
13328 break;
13329 case VMS_SFT_SYMV_IDX:
13330 strcat (res, " VEC");
13331 break;
13332 case VMS_SFT_FD:
13333 strcat (res, " FD");
13334 break;
13335 case VMS_SFT_RESERVE:
13336 strcat (res, " RSV");
13337 break;
13338 default:
13339 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
13340 VMS_ST_FUNC_TYPE (other));
13341 strcat (res, " <unknown>");
13342 break;
13344 break;
13345 default:
13346 break;
13348 switch (VMS_ST_LINKAGE (other))
13350 case VMS_STL_IGNORE:
13351 strcat (res, " IGN");
13352 break;
13353 case VMS_STL_RESERVE:
13354 strcat (res, " RSV");
13355 break;
13356 case VMS_STL_STD:
13357 strcat (res, " STD");
13358 break;
13359 case VMS_STL_LNK:
13360 strcat (res, " LNK");
13361 break;
13362 default:
13363 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
13364 VMS_ST_LINKAGE (other));
13365 strcat (res, " <unknown>");
13366 break;
13369 if (res[0] != 0)
13370 return res + 1;
13371 else
13372 return res;
13374 return NULL;
13377 static const char *
13378 get_ppc64_symbol_other (unsigned int other)
13380 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
13381 return NULL;
13383 other >>= STO_PPC64_LOCAL_BIT;
13384 if (other <= 6)
13386 static char buf[64];
13387 if (other >= 2)
13388 other = ppc64_decode_local_entry (other);
13389 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
13390 return buf;
13392 return NULL;
13395 static const char *
13396 get_riscv_symbol_other (unsigned int other)
13398 static char buf[32];
13399 buf[0] = 0;
13401 if (other & STO_RISCV_VARIANT_CC)
13403 strcat (buf, _(" VARIANT_CC"));
13404 other &= ~STO_RISCV_VARIANT_CC;
13407 if (other != 0)
13408 snprintf (buf, sizeof buf, " %x", other);
13411 if (buf[0] != 0)
13412 return buf + 1;
13413 else
13414 return buf;
13417 static const char *
13418 get_symbol_other (Filedata * filedata, unsigned int other)
13420 const char * result = NULL;
13421 static char buff [64];
13423 if (other == 0)
13424 return "";
13426 switch (filedata->file_header.e_machine)
13428 case EM_ALPHA:
13429 result = get_alpha_symbol_other (other);
13430 break;
13431 case EM_AARCH64:
13432 result = get_aarch64_symbol_other (other);
13433 break;
13434 case EM_MIPS:
13435 result = get_mips_symbol_other (other);
13436 break;
13437 case EM_IA_64:
13438 result = get_ia64_symbol_other (filedata, other);
13439 break;
13440 case EM_PPC64:
13441 result = get_ppc64_symbol_other (other);
13442 break;
13443 case EM_RISCV:
13444 result = get_riscv_symbol_other (other);
13445 break;
13446 default:
13447 result = NULL;
13448 break;
13451 if (result)
13452 return result;
13454 snprintf (buff, sizeof buff, _("<other>: %x"), other);
13455 return buff;
13458 static const char *
13459 get_symbol_version_string (Filedata *filedata,
13460 bool is_dynsym,
13461 const char *strtab,
13462 size_t strtab_size,
13463 unsigned int si,
13464 Elf_Internal_Sym *psym,
13465 enum versioned_symbol_info *sym_info,
13466 unsigned short *vna_other)
13468 unsigned char data[2];
13469 unsigned short vers_data;
13470 uint64_t offset;
13471 unsigned short max_vd_ndx;
13473 if (!is_dynsym
13474 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
13475 return NULL;
13477 offset = offset_from_vma (filedata,
13478 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
13479 sizeof data + si * sizeof (vers_data));
13481 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
13482 sizeof (data), 1, _("version data")) == NULL)
13483 return NULL;
13485 vers_data = byte_get (data, 2);
13487 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
13488 return NULL;
13490 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
13491 max_vd_ndx = 0;
13493 /* Usually we'd only see verdef for defined symbols, and verneed for
13494 undefined symbols. However, symbols defined by the linker in
13495 .dynbss for variables copied from a shared library in order to
13496 avoid text relocations are defined yet have verneed. We could
13497 use a heuristic to detect the special case, for example, check
13498 for verneed first on symbols defined in SHT_NOBITS sections, but
13499 it is simpler and more reliable to just look for both verdef and
13500 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
13502 if (psym->st_shndx != SHN_UNDEF
13503 && vers_data != 0x8001
13504 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
13506 Elf_Internal_Verdef ivd;
13507 Elf_Internal_Verdaux ivda;
13508 Elf_External_Verdaux evda;
13509 uint64_t off;
13511 off = offset_from_vma (filedata,
13512 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
13513 sizeof (Elf_External_Verdef));
13517 Elf_External_Verdef evd;
13519 if (get_data (&evd, filedata, off, sizeof (evd), 1,
13520 _("version def")) == NULL)
13522 ivd.vd_ndx = 0;
13523 ivd.vd_aux = 0;
13524 ivd.vd_next = 0;
13525 ivd.vd_flags = 0;
13527 else
13529 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13530 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13531 ivd.vd_next = BYTE_GET (evd.vd_next);
13532 ivd.vd_flags = BYTE_GET (evd.vd_flags);
13535 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
13536 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
13538 off += ivd.vd_next;
13540 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
13542 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
13544 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
13545 return NULL;
13547 off -= ivd.vd_next;
13548 off += ivd.vd_aux;
13550 if (get_data (&evda, filedata, off, sizeof (evda), 1,
13551 _("version def aux")) != NULL)
13553 ivda.vda_name = BYTE_GET (evda.vda_name);
13555 if (psym->st_name != ivda.vda_name)
13556 return (ivda.vda_name < strtab_size
13557 ? strtab + ivda.vda_name : _("<corrupt>"));
13562 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
13564 Elf_External_Verneed evn;
13565 Elf_Internal_Verneed ivn;
13566 Elf_Internal_Vernaux ivna;
13568 offset = offset_from_vma (filedata,
13569 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
13570 sizeof evn);
13573 uint64_t vna_off;
13575 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
13576 _("version need")) == NULL)
13578 ivna.vna_next = 0;
13579 ivna.vna_other = 0;
13580 ivna.vna_name = 0;
13581 break;
13584 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13585 ivn.vn_next = BYTE_GET (evn.vn_next);
13587 vna_off = offset + ivn.vn_aux;
13591 Elf_External_Vernaux evna;
13593 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
13594 _("version need aux (3)")) == NULL)
13596 ivna.vna_next = 0;
13597 ivna.vna_other = 0;
13598 ivna.vna_name = 0;
13600 else
13602 ivna.vna_other = BYTE_GET (evna.vna_other);
13603 ivna.vna_next = BYTE_GET (evna.vna_next);
13604 ivna.vna_name = BYTE_GET (evna.vna_name);
13607 vna_off += ivna.vna_next;
13609 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
13611 if (ivna.vna_other == vers_data)
13612 break;
13614 offset += ivn.vn_next;
13616 while (ivn.vn_next != 0);
13618 if (ivna.vna_other == vers_data)
13620 *sym_info = symbol_undefined;
13621 *vna_other = ivna.vna_other;
13622 return (ivna.vna_name < strtab_size
13623 ? strtab + ivna.vna_name : _("<corrupt>"));
13625 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
13626 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
13627 return _("<corrupt>");
13629 return NULL;
13632 /* Display a symbol size on stdout. Format is based on --sym-base setting. */
13634 static unsigned int
13635 print_symbol_size (uint64_t vma, int base)
13637 switch (base)
13639 case 8:
13640 return print_vma (vma, OCTAL_5);
13642 case 10:
13643 return print_vma (vma, UNSIGNED_5);
13645 case 16:
13646 return print_vma (vma, PREFIX_HEX_5);
13648 case 0:
13649 default:
13650 return print_vma (vma, DEC_5);
13654 /* Print information on a single symbol. */
13656 static void
13657 print_symbol (Filedata * filedata,
13658 uint64_t symbol_index,
13659 Elf_Internal_Sym * symtab,
13660 Elf_Internal_Shdr * section,
13661 char * strtab,
13662 size_t strtab_size)
13664 const char *version_string;
13665 enum versioned_symbol_info sym_info;
13666 unsigned short vna_other;
13667 const char * sstr;
13668 Elf_Internal_Sym *psym = symtab + symbol_index;
13670 /* FIXME: We should have a table of field widths,
13671 rather than using hard coded constants. */
13672 printf ("%6" PRId64 ": ", symbol_index);
13673 print_vma (psym->st_value, LONG_HEX);
13674 putchar (' ');
13675 print_symbol_size (psym->st_size, sym_base);
13676 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13677 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13678 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13679 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13680 else
13682 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
13684 printf (" %-7s", get_symbol_visibility (vis));
13686 /* Check to see if any other bits in the st_other field are set.
13687 FIXME: Displaying this information here disrupts the layout
13688 of the table being generated. */
13689 if (psym->st_other ^ vis)
13690 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
13693 bool is_special;
13695 sstr = printable_section_name_from_index (filedata, psym->st_shndx, & is_special);
13697 /* Print the symbol's section index. If the index is special
13698 then print the index's name rather than its number. */
13699 if (is_special)
13701 int printed;
13703 /* Special case: If there are no section headers, and the printable
13704 name is "<section 0x...." then just display the section number
13705 as a decimal. This happens when objcopy --strip -section-headers
13706 is used. */
13707 if (filedata->file_header.e_shnum == 0 && startswith (sstr, "<section"))
13708 printed = printf (" %4d ", psym->st_shndx);
13709 else
13710 printed = printf (" %4s ", sstr);
13712 if (extra_sym_info && printed < 16)
13713 printf ("%*s", 16 - printed, "");
13715 else
13717 printf (" %4u ", psym->st_shndx);
13719 if (extra_sym_info)
13721 /* Display the section name referenced by the section index. */
13722 int printed = printf ("(%s) ", sstr);
13723 if (printed < 10)
13724 printf ("%*s", 10 - printed, "");
13728 /* Get the symbol's name. For section symbols without a
13729 specific name use the (already computed) section name. */
13730 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
13731 && section_index_real (filedata, psym->st_shndx)
13732 && psym->st_name == 0)
13736 else
13738 bool is_valid;
13740 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
13741 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13744 version_string
13745 = get_symbol_version_string (filedata,
13746 (section == NULL
13747 || section->sh_type == SHT_DYNSYM),
13748 strtab, strtab_size, symbol_index,
13749 psym, &sym_info, &vna_other);
13751 int len_avail = 21;
13752 if (! do_wide && version_string != NULL)
13754 char buffer[16];
13756 len_avail -= 1 + strlen (version_string);
13758 if (sym_info == symbol_undefined)
13759 len_avail -= sprintf (buffer," (%d)", vna_other);
13760 else if (sym_info != symbol_hidden)
13761 len_avail -= 1;
13764 print_symbol_name (len_avail, sstr);
13766 if (version_string)
13768 if (sym_info == symbol_undefined)
13769 printf ("@%s (%d)", version_string, vna_other);
13770 else
13771 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13772 version_string);
13775 putchar ('\n');
13777 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13778 && section != NULL
13779 && symbol_index >= section->sh_info
13780 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13781 && filedata->file_header.e_machine != EM_MIPS
13782 /* Solaris binaries have been found to violate this requirement as
13783 well. Not sure if this is a bug or an ABI requirement. */
13784 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
13785 warn (_("local symbol %" PRIu64 " found at index >= %s's sh_info value of %u\n"),
13786 symbol_index, printable_section_name (filedata, section), section->sh_info);
13789 static const char *
13790 get_lto_kind (unsigned int kind)
13792 switch (kind)
13794 case 0: return "DEF";
13795 case 1: return "WEAKDEF";
13796 case 2: return "UNDEF";
13797 case 3: return "WEAKUNDEF";
13798 case 4: return "COMMON";
13799 default:
13800 break;
13803 static char buffer[30];
13804 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13805 sprintf (buffer, "<unknown: %u>", kind);
13806 return buffer;
13809 static const char *
13810 get_lto_visibility (unsigned int visibility)
13812 switch (visibility)
13814 case 0: return "DEFAULT";
13815 case 1: return "PROTECTED";
13816 case 2: return "INTERNAL";
13817 case 3: return "HIDDEN";
13818 default:
13819 break;
13822 static char buffer[30];
13823 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13824 sprintf (buffer, "<unknown: %u>", visibility);
13825 return buffer;
13828 static const char *
13829 get_lto_sym_type (unsigned int sym_type)
13831 switch (sym_type)
13833 case 0: return "UNKNOWN";
13834 case 1: return "FUNCTION";
13835 case 2: return "VARIABLE";
13836 default:
13837 break;
13840 static char buffer[30];
13841 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13842 sprintf (buffer, "<unknown: %u>", sym_type);
13843 return buffer;
13846 /* Display an LTO format symbol table.
13847 FIXME: The format of LTO symbol tables is not formalized.
13848 So this code could need changing in the future. */
13850 static bool
13851 display_lto_symtab (Filedata * filedata,
13852 Elf_Internal_Shdr * section)
13854 if (section->sh_size == 0)
13856 if (filedata->is_separate)
13857 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13858 printable_section_name (filedata, section),
13859 filedata->file_name);
13860 else
13861 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13862 printable_section_name (filedata, section));
13864 return true;
13867 if (section->sh_size > filedata->file_size)
13869 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
13870 printable_section_name (filedata, section),
13871 section->sh_size);
13872 return false;
13875 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13876 section->sh_size, 1, _("LTO symbols"));
13877 if (alloced_data == NULL)
13878 return false;
13880 /* Look for extended data for the symbol table. */
13881 Elf_Internal_Shdr * ext = NULL;
13882 void * ext_data_orig = NULL;
13883 char * ext_data = NULL;
13884 char * ext_data_end = NULL;
13885 char * ext_name = NULL;
13887 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
13888 (section_name (filedata, section)
13889 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
13890 && ext_name != NULL /* Paranoia. */
13891 && (ext = find_section (filedata, ext_name)) != NULL)
13893 if (ext->sh_size < 3)
13894 error (_("LTO Symbol extension table '%s' is empty!\n"),
13895 printable_section_name (filedata, ext));
13896 else
13898 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13899 ext->sh_size, 1,
13900 _("LTO ext symbol data"));
13901 if (ext_data != NULL)
13903 ext_data_end = ext_data + ext->sh_size;
13904 if (* ext_data++ != 1)
13905 error (_("Unexpected version number in symbol extension table\n"));
13910 const unsigned char * data = (const unsigned char *) alloced_data;
13911 const unsigned char * end = data + section->sh_size;
13913 if (filedata->is_separate)
13914 printf (_("\nIn linked file '%s': "), filedata->file_name);
13915 else
13916 printf ("\n");
13918 if (ext_data_orig != NULL)
13920 if (do_wide)
13921 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
13922 printable_section_name (filedata, section),
13923 printable_section_name (filedata, ext));
13924 else
13926 printf (_("LTO Symbol table '%s'\n"),
13927 printable_section_name (filedata, section));
13928 printf (_(" and extension table '%s' contain:\n"),
13929 printable_section_name (filedata, ext));
13932 else
13933 printf (_("LTO Symbol table '%s' contains:\n"),
13934 printable_section_name (filedata, section));
13936 /* FIXME: Add a wide version. */
13937 if (ext_data_orig != NULL)
13938 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13939 else
13940 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13942 /* FIXME: We do not handle style prefixes. */
13944 while (data < end)
13946 const unsigned char * sym_name = data;
13947 data += strnlen ((const char *) sym_name, end - data) + 1;
13948 if (data >= end)
13949 goto fail;
13951 const unsigned char * comdat_key = data;
13952 data += strnlen ((const char *) comdat_key, end - data) + 1;
13953 if (data >= end)
13954 goto fail;
13956 if (data + 2 + 8 + 4 > end)
13957 goto fail;
13959 unsigned int kind = *data++;
13960 unsigned int visibility = *data++;
13962 uint64_t size = byte_get (data, 8);
13963 data += 8;
13965 uint64_t slot = byte_get (data, 4);
13966 data += 4;
13968 if (ext_data != NULL)
13970 if (ext_data < (ext_data_end - 1))
13972 unsigned int sym_type = * ext_data ++;
13973 unsigned int sec_kind = * ext_data ++;
13975 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " %9s %08x _",
13976 * comdat_key == 0 ? "-" : (char *) comdat_key,
13977 get_lto_kind (kind),
13978 get_lto_visibility (visibility),
13979 size,
13980 slot,
13981 get_lto_sym_type (sym_type),
13982 sec_kind);
13983 print_symbol_name (6, (const char *) sym_name);
13985 else
13987 error (_("Ran out of LTO symbol extension data\n"));
13988 ext_data = NULL;
13989 /* FIXME: return FAIL result ? */
13992 else
13994 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " _",
13995 * comdat_key == 0 ? "-" : (char *) comdat_key,
13996 get_lto_kind (kind),
13997 get_lto_visibility (visibility),
13998 size,
13999 slot);
14000 print_symbol_name (21, (const char *) sym_name);
14002 putchar ('\n');
14005 if (ext_data != NULL && ext_data < ext_data_end)
14007 error (_("Data remains in the LTO symbol extension table\n"));
14008 goto fail;
14011 free (alloced_data);
14012 free (ext_data_orig);
14013 free (ext_name);
14014 return true;
14016 fail:
14017 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
14018 free (alloced_data);
14019 free (ext_data_orig);
14020 free (ext_name);
14021 return false;
14024 /* Display LTO symbol tables. */
14026 static bool
14027 process_lto_symbol_tables (Filedata * filedata)
14029 Elf_Internal_Shdr * section;
14030 unsigned int i;
14031 bool res = true;
14033 if (!do_lto_syms)
14034 return true;
14036 if (filedata->section_headers == NULL)
14037 return true;
14039 for (i = 0, section = filedata->section_headers;
14040 i < filedata->file_header.e_shnum;
14041 i++, section++)
14042 if (section_name_valid (filedata, section)
14043 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
14044 res &= display_lto_symtab (filedata, section);
14046 return res;
14049 static void
14050 print_symbol_table_heading (void)
14052 /* FIXME: We should store the size of each field in the display in a table and
14053 then use the values inside print_symbol(), instead of that function using
14054 hard coded constants. */
14055 if (is_32bit_elf)
14057 if (extra_sym_info)
14059 printf (_(" Num: Value Size Type Bind Vis+Other Ndx(SecName) Name [+ Version Info]\n"));
14060 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |---8--| |----13.....| |........... */
14061 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 (.text) get_sections */
14063 else if (do_wide)
14065 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14066 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |-4| |........... */
14067 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 get_sections */
14069 else
14071 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14072 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |-4| |------------29-------------| */
14073 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 get_sections */
14076 else
14078 if (extra_sym_info)
14080 printf (_(" Num: Value Size Type Bind Vis+Other Ndx(SecName) Name [+ Version Info]\n"));
14081 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-------14---| |..... */
14082 /* eg: 2: 0000000000000000 0 FUNC LOCAL DEFAULT 1 (.text) .very_long_function_name */
14085 else if (do_wide)
14087 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14088 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-4| |........... */
14089 /* eg: 5: 0000000000000000 14 FUNC LOCAL DEFAULT 1 very_long_function_name */
14091 else
14093 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14094 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-4| |--------21---------| */
14095 /* eg: 5: 0000000000000000 14 FUNC LOCAL DEFAULT 1 very_long_functi[...] */
14100 /* Dump the symbol table. */
14102 static bool
14103 process_symbol_table (Filedata * filedata)
14105 Elf_Internal_Shdr * section;
14107 if (!do_syms && !do_dyn_syms && !do_histogram)
14108 return true;
14110 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
14111 && do_syms
14112 && do_using_dynamic
14113 && filedata->dynamic_strings != NULL
14114 && filedata->dynamic_symbols != NULL)
14116 uint64_t si;
14118 if (filedata->is_separate)
14120 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table"
14121 " contains %" PRIu64 " entry:\n",
14122 "\nIn linked file '%s' the dynamic symbol table"
14123 " contains %" PRIu64 " entries:\n",
14124 filedata->num_dynamic_syms),
14125 filedata->file_name,
14126 filedata->num_dynamic_syms);
14128 else
14130 printf (ngettext ("\nSymbol table for image contains %" PRIu64
14131 " entry:\n",
14132 "\nSymbol table for image contains %" PRIu64
14133 " entries:\n",
14134 filedata->num_dynamic_syms),
14135 filedata->num_dynamic_syms);
14138 print_symbol_table_heading ();
14140 for (si = 0; si < filedata->num_dynamic_syms; si++)
14141 print_symbol (filedata, si, filedata->dynamic_symbols, NULL,
14142 filedata->dynamic_strings,
14143 filedata->dynamic_strings_length);
14145 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
14146 && filedata->section_headers != NULL)
14148 unsigned int i;
14150 for (i = 0, section = filedata->section_headers;
14151 i < filedata->file_header.e_shnum;
14152 i++, section++)
14154 char * strtab = NULL;
14155 uint64_t strtab_size = 0;
14156 Elf_Internal_Sym * symtab;
14157 uint64_t si, num_syms;
14159 if ((section->sh_type != SHT_SYMTAB
14160 && section->sh_type != SHT_DYNSYM)
14161 || (!do_syms
14162 && section->sh_type == SHT_SYMTAB))
14163 continue;
14165 if (section->sh_entsize == 0)
14167 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
14168 printable_section_name (filedata, section));
14169 continue;
14172 num_syms = section->sh_size / section->sh_entsize;
14174 if (filedata->is_separate)
14175 printf (ngettext ("\nIn linked file '%s' symbol section '%s'"
14176 " contains %" PRIu64 " entry:\n",
14177 "\nIn linked file '%s' symbol section '%s'"
14178 " contains %" PRIu64 " entries:\n",
14179 num_syms),
14180 filedata->file_name,
14181 printable_section_name (filedata, section),
14182 num_syms);
14183 else
14184 printf (ngettext ("\nSymbol table '%s' contains %" PRIu64
14185 " entry:\n",
14186 "\nSymbol table '%s' contains %" PRIu64
14187 " entries:\n",
14188 num_syms),
14189 printable_section_name (filedata, section),
14190 num_syms);
14192 print_symbol_table_heading ();
14194 symtab = get_elf_symbols (filedata, section, & num_syms);
14195 if (symtab == NULL)
14196 continue;
14198 if (section->sh_link == filedata->file_header.e_shstrndx)
14200 strtab = filedata->string_table;
14201 strtab_size = filedata->string_table_length;
14203 else if (section->sh_link < filedata->file_header.e_shnum)
14205 Elf_Internal_Shdr * string_sec;
14207 string_sec = filedata->section_headers + section->sh_link;
14209 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
14210 1, string_sec->sh_size,
14211 _("string table"));
14212 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
14215 for (si = 0; si < num_syms; si++)
14216 print_symbol (filedata, si, symtab, section,
14217 strtab, strtab_size);
14219 free (symtab);
14220 if (strtab != filedata->string_table)
14221 free (strtab);
14224 else if (do_syms)
14225 printf
14226 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
14228 if (do_histogram && filedata->buckets != NULL)
14230 uint64_t *lengths;
14231 uint64_t *counts;
14232 uint64_t hn;
14233 uint64_t si;
14234 uint64_t maxlength = 0;
14235 uint64_t nzero_counts = 0;
14236 uint64_t nsyms = 0;
14237 char *visited;
14239 printf (ngettext ("\nHistogram for bucket list length "
14240 "(total of %" PRIu64 " bucket):\n",
14241 "\nHistogram for bucket list length "
14242 "(total of %" PRIu64 " buckets):\n",
14243 filedata->nbuckets),
14244 filedata->nbuckets);
14246 lengths = calloc (filedata->nbuckets, sizeof (*lengths));
14247 if (lengths == NULL)
14249 error (_("Out of memory allocating space for histogram buckets\n"));
14250 goto err_out;
14252 visited = xcmalloc (filedata->nchains, 1);
14253 memset (visited, 0, filedata->nchains);
14255 printf (_(" Length Number %% of total Coverage\n"));
14256 for (hn = 0; hn < filedata->nbuckets; ++hn)
14258 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
14260 ++nsyms;
14261 if (maxlength < ++lengths[hn])
14262 ++maxlength;
14263 if (si >= filedata->nchains || visited[si])
14265 error (_("histogram chain is corrupt\n"));
14266 break;
14268 visited[si] = 1;
14271 free (visited);
14273 counts = calloc (maxlength + 1, sizeof (*counts));
14274 if (counts == NULL)
14276 free (lengths);
14277 error (_("Out of memory allocating space for histogram counts\n"));
14278 goto err_out;
14281 for (hn = 0; hn < filedata->nbuckets; ++hn)
14282 ++counts[lengths[hn]];
14284 if (filedata->nbuckets > 0)
14286 uint64_t i;
14287 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
14288 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
14289 for (i = 1; i <= maxlength; ++i)
14291 nzero_counts += counts[i] * i;
14292 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
14293 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
14294 (nzero_counts * 100.0) / nsyms);
14298 free (counts);
14299 free (lengths);
14302 free (filedata->buckets);
14303 filedata->buckets = NULL;
14304 filedata->nbuckets = 0;
14305 free (filedata->chains);
14306 filedata->chains = NULL;
14308 if (do_histogram && filedata->gnubuckets != NULL)
14310 uint64_t *lengths;
14311 uint64_t *counts;
14312 uint64_t hn;
14313 uint64_t maxlength = 0;
14314 uint64_t nzero_counts = 0;
14315 uint64_t nsyms = 0;
14317 printf (ngettext ("\nHistogram for `%s' bucket list length "
14318 "(total of %" PRIu64 " bucket):\n",
14319 "\nHistogram for `%s' bucket list length "
14320 "(total of %" PRIu64 " buckets):\n",
14321 filedata->ngnubuckets),
14322 GNU_HASH_SECTION_NAME (filedata),
14323 filedata->ngnubuckets);
14325 lengths = calloc (filedata->ngnubuckets, sizeof (*lengths));
14326 if (lengths == NULL)
14328 error (_("Out of memory allocating space for gnu histogram buckets\n"));
14329 goto err_out;
14332 printf (_(" Length Number %% of total Coverage\n"));
14334 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
14335 if (filedata->gnubuckets[hn] != 0)
14337 uint64_t off, length = 1;
14339 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
14340 /* PR 17531 file: 010-77222-0.004. */
14341 off < filedata->ngnuchains
14342 && (filedata->gnuchains[off] & 1) == 0;
14343 ++off)
14344 ++length;
14345 lengths[hn] = length;
14346 if (length > maxlength)
14347 maxlength = length;
14348 nsyms += length;
14351 counts = calloc (maxlength + 1, sizeof (*counts));
14352 if (counts == NULL)
14354 free (lengths);
14355 error (_("Out of memory allocating space for gnu histogram counts\n"));
14356 goto err_out;
14359 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
14360 ++counts[lengths[hn]];
14362 if (filedata->ngnubuckets > 0)
14364 uint64_t j;
14365 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
14366 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
14367 for (j = 1; j <= maxlength; ++j)
14369 nzero_counts += counts[j] * j;
14370 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
14371 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
14372 (nzero_counts * 100.0) / nsyms);
14376 free (counts);
14377 free (lengths);
14379 free (filedata->gnubuckets);
14380 filedata->gnubuckets = NULL;
14381 filedata->ngnubuckets = 0;
14382 free (filedata->gnuchains);
14383 filedata->gnuchains = NULL;
14384 filedata->ngnuchains = 0;
14385 free (filedata->mipsxlat);
14386 filedata->mipsxlat = NULL;
14387 return true;
14389 err_out:
14390 free (filedata->gnubuckets);
14391 filedata->gnubuckets = NULL;
14392 filedata->ngnubuckets = 0;
14393 free (filedata->gnuchains);
14394 filedata->gnuchains = NULL;
14395 filedata->ngnuchains = 0;
14396 free (filedata->mipsxlat);
14397 filedata->mipsxlat = NULL;
14398 free (filedata->buckets);
14399 filedata->buckets = NULL;
14400 filedata->nbuckets = 0;
14401 free (filedata->chains);
14402 filedata->chains = NULL;
14403 return false;
14406 static bool
14407 process_syminfo (Filedata * filedata)
14409 unsigned int i;
14411 if (filedata->dynamic_syminfo == NULL
14412 || !do_dynamic)
14413 /* No syminfo, this is ok. */
14414 return true;
14416 /* There better should be a dynamic symbol section. */
14417 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
14418 return false;
14420 if (filedata->is_separate)
14421 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entry:\n",
14422 "\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entries:\n",
14423 filedata->dynamic_syminfo_nent),
14424 filedata->file_name,
14425 filedata->dynamic_syminfo_offset,
14426 filedata->dynamic_syminfo_nent);
14427 else
14428 printf (ngettext ("\nDynamic info segment at offset %#" PRIx64
14429 " contains %d entry:\n",
14430 "\nDynamic info segment at offset %#" PRIx64
14431 " contains %d entries:\n",
14432 filedata->dynamic_syminfo_nent),
14433 filedata->dynamic_syminfo_offset,
14434 filedata->dynamic_syminfo_nent);
14436 printf (_(" Num: Name BoundTo Flags\n"));
14437 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
14439 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
14441 printf ("%4d: ", i);
14442 if (i >= filedata->num_dynamic_syms)
14443 printf (_("<corrupt index>"));
14444 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
14445 print_symbol_name (30, get_dynamic_name (filedata,
14446 filedata->dynamic_symbols[i].st_name));
14447 else
14448 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
14449 putchar (' ');
14451 switch (filedata->dynamic_syminfo[i].si_boundto)
14453 case SYMINFO_BT_SELF:
14454 fputs ("SELF ", stdout);
14455 break;
14456 case SYMINFO_BT_PARENT:
14457 fputs ("PARENT ", stdout);
14458 break;
14459 default:
14460 if (filedata->dynamic_syminfo[i].si_boundto > 0
14461 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
14462 && valid_dynamic_name (filedata,
14463 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
14465 print_symbol_name (10, get_dynamic_name (filedata,
14466 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
14467 putchar (' ' );
14469 else
14470 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
14471 break;
14474 if (flags & SYMINFO_FLG_DIRECT)
14475 printf (" DIRECT");
14476 if (flags & SYMINFO_FLG_PASSTHRU)
14477 printf (" PASSTHRU");
14478 if (flags & SYMINFO_FLG_COPY)
14479 printf (" COPY");
14480 if (flags & SYMINFO_FLG_LAZYLOAD)
14481 printf (" LAZYLOAD");
14483 puts ("");
14486 return true;
14489 /* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
14490 is contained by the region START .. END. The types of ADDR, START
14491 and END should all be the same. Note both ADDR + NELEM and END
14492 point to just beyond the end of the regions that are being tested. */
14493 #define IN_RANGE(START,END,ADDR,NELEM) \
14494 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
14496 /* Check to see if the given reloc needs to be handled in a target specific
14497 manner. If so then process the reloc and return TRUE otherwise return
14498 FALSE.
14500 If called with reloc == NULL, then this is a signal that reloc processing
14501 for the current section has finished, and any saved state should be
14502 discarded. */
14504 static bool
14505 target_specific_reloc_handling (Filedata *filedata,
14506 Elf_Internal_Rela *reloc,
14507 unsigned char *start,
14508 unsigned char *end,
14509 Elf_Internal_Sym *symtab,
14510 uint64_t num_syms)
14512 unsigned int reloc_type = 0;
14513 uint64_t sym_index = 0;
14515 if (reloc)
14517 reloc_type = get_reloc_type (filedata, reloc->r_info);
14518 sym_index = get_reloc_symindex (reloc->r_info);
14521 switch (filedata->file_header.e_machine)
14523 case EM_LOONGARCH:
14525 switch (reloc_type)
14527 /* For .uleb128 .LFE1-.LFB1, loongarch write 0 to object file
14528 at assembly time. */
14529 case 107: /* R_LARCH_ADD_ULEB128. */
14530 case 108: /* R_LARCH_SUB_ULEB128. */
14532 uint64_t value = 0;
14533 unsigned int reloc_size = 0;
14534 int leb_ret = 0;
14536 if (reloc->r_offset < (size_t) (end - start))
14537 value = read_leb128 (start + reloc->r_offset, end, false,
14538 &reloc_size, &leb_ret);
14539 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
14540 error (_("LoongArch ULEB128 field at 0x%lx contains invalid "
14541 "ULEB128 value\n"),
14542 (long) reloc->r_offset);
14544 else if (sym_index >= num_syms)
14545 error (_("%s reloc contains invalid symbol index "
14546 "%" PRIu64 "\n"),
14547 (reloc_type == 107
14548 ? "R_LARCH_ADD_ULEB128"
14549 : "R_LARCH_SUB_ULEB128"),
14550 sym_index);
14551 else
14553 if (reloc_type == 107)
14554 value += reloc->r_addend + symtab[sym_index].st_value;
14555 else
14556 value -= reloc->r_addend + symtab[sym_index].st_value;
14558 /* Write uleb128 value to p. */
14559 bfd_byte *p = start + reloc->r_offset;
14562 bfd_byte c = value & 0x7f;
14563 value >>= 7;
14564 if (--reloc_size != 0)
14565 c |= 0x80;
14566 *p++ = c;
14568 while (reloc_size);
14571 return true;
14574 break;
14577 case EM_MSP430:
14578 case EM_MSP430_OLD:
14580 static Elf_Internal_Sym * saved_sym = NULL;
14582 if (reloc == NULL)
14584 saved_sym = NULL;
14585 return true;
14588 switch (reloc_type)
14590 case 10: /* R_MSP430_SYM_DIFF */
14591 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
14592 if (uses_msp430x_relocs (filedata))
14593 break;
14594 /* Fall through. */
14595 case 21: /* R_MSP430X_SYM_DIFF */
14596 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
14597 /* PR 21139. */
14598 if (sym_index >= num_syms)
14599 error (_("%s reloc contains invalid symbol index "
14600 "%" PRIu64 "\n"), "MSP430 SYM_DIFF", sym_index);
14601 else
14602 saved_sym = symtab + sym_index;
14603 return true;
14605 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14606 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
14607 goto handle_sym_diff;
14609 case 5: /* R_MSP430_16_BYTE */
14610 case 9: /* R_MSP430_8 */
14611 case 11: /* R_MSP430_GNU_SET_ULEB128 */
14612 if (uses_msp430x_relocs (filedata))
14613 break;
14614 goto handle_sym_diff;
14616 case 2: /* R_MSP430_ABS16 */
14617 case 15: /* R_MSP430X_ABS16 */
14618 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
14619 if (! uses_msp430x_relocs (filedata))
14620 break;
14621 goto handle_sym_diff;
14623 handle_sym_diff:
14624 if (saved_sym != NULL)
14626 uint64_t value;
14627 unsigned int reloc_size = 0;
14628 int leb_ret = 0;
14629 switch (reloc_type)
14631 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14632 reloc_size = 4;
14633 break;
14634 case 11: /* R_MSP430_GNU_SET_ULEB128 */
14635 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
14636 if (reloc->r_offset < (size_t) (end - start))
14637 read_leb128 (start + reloc->r_offset, end, false,
14638 &reloc_size, &leb_ret);
14639 break;
14640 default:
14641 reloc_size = 2;
14642 break;
14645 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
14646 error (_("MSP430 ULEB128 field at %#" PRIx64
14647 " contains invalid ULEB128 value\n"),
14648 reloc->r_offset);
14649 else if (sym_index >= num_syms)
14650 error (_("%s reloc contains invalid symbol index "
14651 "%" PRIu64 "\n"), "MSP430", sym_index);
14652 else
14654 value = reloc->r_addend + (symtab[sym_index].st_value
14655 - saved_sym->st_value);
14657 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
14658 byte_put (start + reloc->r_offset, value, reloc_size);
14659 else
14660 /* PR 21137 */
14661 error (_("MSP430 sym diff reloc contains invalid offset: "
14662 "%#" PRIx64 "\n"),
14663 reloc->r_offset);
14666 saved_sym = NULL;
14667 return true;
14669 break;
14671 default:
14672 if (saved_sym != NULL)
14673 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
14674 break;
14676 break;
14679 case EM_MN10300:
14680 case EM_CYGNUS_MN10300:
14682 static Elf_Internal_Sym * saved_sym = NULL;
14684 if (reloc == NULL)
14686 saved_sym = NULL;
14687 return true;
14690 switch (reloc_type)
14692 case 34: /* R_MN10300_ALIGN */
14693 return true;
14694 case 33: /* R_MN10300_SYM_DIFF */
14695 if (sym_index >= num_syms)
14696 error (_("%s reloc contains invalid symbol index "
14697 "%" PRIu64 "\n"), "MN10300_SYM_DIFF", sym_index);
14698 else
14699 saved_sym = symtab + sym_index;
14700 return true;
14702 case 1: /* R_MN10300_32 */
14703 case 2: /* R_MN10300_16 */
14704 if (saved_sym != NULL)
14706 int reloc_size = reloc_type == 1 ? 4 : 2;
14707 uint64_t value;
14709 if (sym_index >= num_syms)
14710 error (_("%s reloc contains invalid symbol index "
14711 "%" PRIu64 "\n"), "MN10300", sym_index);
14712 else
14714 value = reloc->r_addend + (symtab[sym_index].st_value
14715 - saved_sym->st_value);
14717 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
14718 byte_put (start + reloc->r_offset, value, reloc_size);
14719 else
14720 error (_("MN10300 sym diff reloc contains invalid offset:"
14721 " %#" PRIx64 "\n"),
14722 reloc->r_offset);
14725 saved_sym = NULL;
14726 return true;
14728 break;
14729 default:
14730 if (saved_sym != NULL)
14731 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
14732 break;
14734 break;
14737 case EM_RL78:
14739 static uint64_t saved_sym1 = 0;
14740 static uint64_t saved_sym2 = 0;
14741 static uint64_t value;
14743 if (reloc == NULL)
14745 saved_sym1 = saved_sym2 = 0;
14746 return true;
14749 switch (reloc_type)
14751 case 0x80: /* R_RL78_SYM. */
14752 saved_sym1 = saved_sym2;
14753 if (sym_index >= num_syms)
14754 error (_("%s reloc contains invalid symbol index "
14755 "%" PRIu64 "\n"), "RL78_SYM", sym_index);
14756 else
14758 saved_sym2 = symtab[sym_index].st_value;
14759 saved_sym2 += reloc->r_addend;
14761 return true;
14763 case 0x83: /* R_RL78_OPsub. */
14764 value = saved_sym1 - saved_sym2;
14765 saved_sym2 = saved_sym1 = 0;
14766 return true;
14767 break;
14769 case 0x41: /* R_RL78_ABS32. */
14770 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
14771 byte_put (start + reloc->r_offset, value, 4);
14772 else
14773 error (_("RL78 sym diff reloc contains invalid offset: "
14774 "%#" PRIx64 "\n"),
14775 reloc->r_offset);
14776 value = 0;
14777 return true;
14779 case 0x43: /* R_RL78_ABS16. */
14780 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
14781 byte_put (start + reloc->r_offset, value, 2);
14782 else
14783 error (_("RL78 sym diff reloc contains invalid offset: "
14784 "%#" PRIx64 "\n"),
14785 reloc->r_offset);
14786 value = 0;
14787 return true;
14789 default:
14790 break;
14792 break;
14796 return false;
14799 /* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
14800 DWARF debug sections. This is a target specific test. Note - we do not
14801 go through the whole including-target-headers-multiple-times route, (as
14802 we have already done with <elf/h8.h>) because this would become very
14803 messy and even then this function would have to contain target specific
14804 information (the names of the relocs instead of their numeric values).
14805 FIXME: This is not the correct way to solve this problem. The proper way
14806 is to have target specific reloc sizing and typing functions created by
14807 the reloc-macros.h header, in the same way that it already creates the
14808 reloc naming functions. */
14810 static bool
14811 is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14813 /* Please keep this table alpha-sorted for ease of visual lookup. */
14814 switch (filedata->file_header.e_machine)
14816 case EM_386:
14817 case EM_IAMCU:
14818 return reloc_type == 1; /* R_386_32. */
14819 case EM_68K:
14820 return reloc_type == 1; /* R_68K_32. */
14821 case EM_860:
14822 return reloc_type == 1; /* R_860_32. */
14823 case EM_960:
14824 return reloc_type == 2; /* R_960_32. */
14825 case EM_AARCH64:
14826 return (reloc_type == 258
14827 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
14828 case EM_BPF:
14829 return reloc_type == 11; /* R_BPF_DATA_32 */
14830 case EM_ADAPTEVA_EPIPHANY:
14831 return reloc_type == 3;
14832 case EM_ALPHA:
14833 return reloc_type == 1; /* R_ALPHA_REFLONG. */
14834 case EM_ARC:
14835 return reloc_type == 1; /* R_ARC_32. */
14836 case EM_ARC_COMPACT:
14837 case EM_ARC_COMPACT2:
14838 case EM_ARC_COMPACT3:
14839 case EM_ARC_COMPACT3_64:
14840 return reloc_type == 4; /* R_ARC_32. */
14841 case EM_ARM:
14842 return reloc_type == 2; /* R_ARM_ABS32 */
14843 case EM_AVR_OLD:
14844 case EM_AVR:
14845 return reloc_type == 1;
14846 case EM_BLACKFIN:
14847 return reloc_type == 0x12; /* R_byte4_data. */
14848 case EM_CRIS:
14849 return reloc_type == 3; /* R_CRIS_32. */
14850 case EM_CR16:
14851 return reloc_type == 3; /* R_CR16_NUM32. */
14852 case EM_CRX:
14853 return reloc_type == 15; /* R_CRX_NUM32. */
14854 case EM_CSKY:
14855 return reloc_type == 1; /* R_CKCORE_ADDR32. */
14856 case EM_CYGNUS_FRV:
14857 return reloc_type == 1;
14858 case EM_CYGNUS_D10V:
14859 case EM_D10V:
14860 return reloc_type == 6; /* R_D10V_32. */
14861 case EM_CYGNUS_D30V:
14862 case EM_D30V:
14863 return reloc_type == 12; /* R_D30V_32_NORMAL. */
14864 case EM_DLX:
14865 return reloc_type == 3; /* R_DLX_RELOC_32. */
14866 case EM_CYGNUS_FR30:
14867 case EM_FR30:
14868 return reloc_type == 3; /* R_FR30_32. */
14869 case EM_FT32:
14870 return reloc_type == 1; /* R_FT32_32. */
14871 case EM_H8S:
14872 case EM_H8_300:
14873 case EM_H8_300H:
14874 return reloc_type == 1; /* R_H8_DIR32. */
14875 case EM_IA_64:
14876 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14877 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14878 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14879 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
14880 case EM_IP2K_OLD:
14881 case EM_IP2K:
14882 return reloc_type == 2; /* R_IP2K_32. */
14883 case EM_IQ2000:
14884 return reloc_type == 2; /* R_IQ2000_32. */
14885 case EM_KVX:
14886 return reloc_type == 2; /* R_KVX_32. */
14887 case EM_LATTICEMICO32:
14888 return reloc_type == 3; /* R_LM32_32. */
14889 case EM_LOONGARCH:
14890 return reloc_type == 1; /* R_LARCH_32. */
14891 case EM_M32C_OLD:
14892 case EM_M32C:
14893 return reloc_type == 3; /* R_M32C_32. */
14894 case EM_M32R:
14895 return reloc_type == 34; /* R_M32R_32_RELA. */
14896 case EM_68HC11:
14897 case EM_68HC12:
14898 return reloc_type == 6; /* R_M68HC11_32. */
14899 case EM_S12Z:
14900 return reloc_type == 7 || /* R_S12Z_EXT32 */
14901 reloc_type == 6; /* R_S12Z_CW32. */
14902 case EM_MCORE:
14903 return reloc_type == 1; /* R_MCORE_ADDR32. */
14904 case EM_CYGNUS_MEP:
14905 return reloc_type == 4; /* R_MEP_32. */
14906 case EM_METAG:
14907 return reloc_type == 2; /* R_METAG_ADDR32. */
14908 case EM_MICROBLAZE:
14909 return reloc_type == 1; /* R_MICROBLAZE_32. */
14910 case EM_MIPS:
14911 return reloc_type == 2; /* R_MIPS_32. */
14912 case EM_MMIX:
14913 return reloc_type == 4; /* R_MMIX_32. */
14914 case EM_CYGNUS_MN10200:
14915 case EM_MN10200:
14916 return reloc_type == 1; /* R_MN10200_32. */
14917 case EM_CYGNUS_MN10300:
14918 case EM_MN10300:
14919 return reloc_type == 1; /* R_MN10300_32. */
14920 case EM_MOXIE:
14921 return reloc_type == 1; /* R_MOXIE_32. */
14922 case EM_MSP430_OLD:
14923 case EM_MSP430:
14924 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
14925 case EM_MT:
14926 return reloc_type == 2; /* R_MT_32. */
14927 case EM_NDS32:
14928 return reloc_type == 20; /* R_NDS32_32_RELA. */
14929 case EM_ALTERA_NIOS2:
14930 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
14931 case EM_NIOS32:
14932 return reloc_type == 1; /* R_NIOS_32. */
14933 case EM_OR1K:
14934 return reloc_type == 1; /* R_OR1K_32. */
14935 case EM_PARISC:
14936 return (reloc_type == 1 /* R_PARISC_DIR32. */
14937 || reloc_type == 2 /* R_PARISC_DIR21L. */
14938 || reloc_type == 41); /* R_PARISC_SECREL32. */
14939 case EM_PJ:
14940 case EM_PJ_OLD:
14941 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14942 case EM_PPC64:
14943 return reloc_type == 1; /* R_PPC64_ADDR32. */
14944 case EM_PPC:
14945 return reloc_type == 1; /* R_PPC_ADDR32. */
14946 case EM_TI_PRU:
14947 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
14948 case EM_RISCV:
14949 return reloc_type == 1; /* R_RISCV_32. */
14950 case EM_RL78:
14951 return reloc_type == 1; /* R_RL78_DIR32. */
14952 case EM_RX:
14953 return reloc_type == 1; /* R_RX_DIR32. */
14954 case EM_S370:
14955 return reloc_type == 1; /* R_I370_ADDR31. */
14956 case EM_S390_OLD:
14957 case EM_S390:
14958 return reloc_type == 4; /* R_S390_32. */
14959 case EM_SCORE:
14960 return reloc_type == 8; /* R_SCORE_ABS32. */
14961 case EM_SH:
14962 return reloc_type == 1; /* R_SH_DIR32. */
14963 case EM_SPARC32PLUS:
14964 case EM_SPARCV9:
14965 case EM_SPARC:
14966 return reloc_type == 3 /* R_SPARC_32. */
14967 || reloc_type == 23; /* R_SPARC_UA32. */
14968 case EM_SPU:
14969 return reloc_type == 6; /* R_SPU_ADDR32 */
14970 case EM_TI_C6000:
14971 return reloc_type == 1; /* R_C6000_ABS32. */
14972 case EM_TILEGX:
14973 return reloc_type == 2; /* R_TILEGX_32. */
14974 case EM_TILEPRO:
14975 return reloc_type == 1; /* R_TILEPRO_32. */
14976 case EM_CYGNUS_V850:
14977 case EM_V850:
14978 return reloc_type == 6; /* R_V850_ABS32. */
14979 case EM_V800:
14980 return reloc_type == 0x33; /* R_V810_WORD. */
14981 case EM_VAX:
14982 return reloc_type == 1; /* R_VAX_32. */
14983 case EM_VISIUM:
14984 return reloc_type == 3; /* R_VISIUM_32. */
14985 case EM_WEBASSEMBLY:
14986 return reloc_type == 1; /* R_WASM32_32. */
14987 case EM_X86_64:
14988 case EM_L1OM:
14989 case EM_K1OM:
14990 return reloc_type == 10; /* R_X86_64_32. */
14991 case EM_XGATE:
14992 return reloc_type == 4; /* R_XGATE_32. */
14993 case EM_XSTORMY16:
14994 return reloc_type == 1; /* R_XSTROMY16_32. */
14995 case EM_XTENSA_OLD:
14996 case EM_XTENSA:
14997 return reloc_type == 1; /* R_XTENSA_32. */
14998 case EM_Z80:
14999 return reloc_type == 6; /* R_Z80_32. */
15000 default:
15002 static unsigned int prev_warn = 0;
15004 /* Avoid repeating the same warning multiple times. */
15005 if (prev_warn != filedata->file_header.e_machine)
15006 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
15007 filedata->file_header.e_machine);
15008 prev_warn = filedata->file_header.e_machine;
15009 return false;
15014 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15015 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
15017 static bool
15018 is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
15020 switch (filedata->file_header.e_machine)
15021 /* Please keep this table alpha-sorted for ease of visual lookup. */
15023 case EM_386:
15024 case EM_IAMCU:
15025 return reloc_type == 2; /* R_386_PC32. */
15026 case EM_68K:
15027 return reloc_type == 4; /* R_68K_PC32. */
15028 case EM_AARCH64:
15029 return reloc_type == 261; /* R_AARCH64_PREL32 */
15030 case EM_ADAPTEVA_EPIPHANY:
15031 return reloc_type == 6;
15032 case EM_ALPHA:
15033 return reloc_type == 10; /* R_ALPHA_SREL32. */
15034 case EM_ARC_COMPACT:
15035 case EM_ARC_COMPACT2:
15036 case EM_ARC_COMPACT3:
15037 case EM_ARC_COMPACT3_64:
15038 return reloc_type == 49; /* R_ARC_32_PCREL. */
15039 case EM_ARM:
15040 return reloc_type == 3; /* R_ARM_REL32 */
15041 case EM_AVR_OLD:
15042 case EM_AVR:
15043 return reloc_type == 36; /* R_AVR_32_PCREL. */
15044 case EM_LOONGARCH:
15045 return reloc_type == 99; /* R_LARCH_32_PCREL. */
15046 case EM_MICROBLAZE:
15047 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
15048 case EM_OR1K:
15049 return reloc_type == 9; /* R_OR1K_32_PCREL. */
15050 case EM_PARISC:
15051 return reloc_type == 9; /* R_PARISC_PCREL32. */
15052 case EM_PPC:
15053 return reloc_type == 26; /* R_PPC_REL32. */
15054 case EM_PPC64:
15055 return reloc_type == 26; /* R_PPC64_REL32. */
15056 case EM_RISCV:
15057 return reloc_type == 57; /* R_RISCV_32_PCREL. */
15058 case EM_S390_OLD:
15059 case EM_S390:
15060 return reloc_type == 5; /* R_390_PC32. */
15061 case EM_SH:
15062 return reloc_type == 2; /* R_SH_REL32. */
15063 case EM_SPARC32PLUS:
15064 case EM_SPARCV9:
15065 case EM_SPARC:
15066 return reloc_type == 6; /* R_SPARC_DISP32. */
15067 case EM_SPU:
15068 return reloc_type == 13; /* R_SPU_REL32. */
15069 case EM_TILEGX:
15070 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
15071 case EM_TILEPRO:
15072 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
15073 case EM_VISIUM:
15074 return reloc_type == 6; /* R_VISIUM_32_PCREL */
15075 case EM_X86_64:
15076 case EM_L1OM:
15077 case EM_K1OM:
15078 return reloc_type == 2; /* R_X86_64_PC32. */
15079 case EM_VAX:
15080 return reloc_type == 4; /* R_VAX_PCREL32. */
15081 case EM_XTENSA_OLD:
15082 case EM_XTENSA:
15083 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
15084 case EM_KVX:
15085 return reloc_type == 7; /* R_KVX_32_PCREL */
15086 default:
15087 /* Do not abort or issue an error message here. Not all targets use
15088 pc-relative 32-bit relocs in their DWARF debug information and we
15089 have already tested for target coverage in is_32bit_abs_reloc. A
15090 more helpful warning message will be generated by apply_relocations
15091 anyway, so just return. */
15092 return false;
15096 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15097 a 64-bit absolute RELA relocation used in DWARF debug sections. */
15099 static bool
15100 is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15102 switch (filedata->file_header.e_machine)
15104 case EM_AARCH64:
15105 return reloc_type == 257; /* R_AARCH64_ABS64. */
15106 case EM_ARC_COMPACT3_64:
15107 return reloc_type == 5; /* R_ARC_64. */
15108 case EM_ALPHA:
15109 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
15110 case EM_IA_64:
15111 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
15112 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
15113 case EM_LOONGARCH:
15114 return reloc_type == 2; /* R_LARCH_64 */
15115 case EM_PARISC:
15116 return reloc_type == 80; /* R_PARISC_DIR64. */
15117 case EM_PPC64:
15118 return reloc_type == 38; /* R_PPC64_ADDR64. */
15119 case EM_RISCV:
15120 return reloc_type == 2; /* R_RISCV_64. */
15121 case EM_SPARC32PLUS:
15122 case EM_SPARCV9:
15123 case EM_SPARC:
15124 return reloc_type == 32 /* R_SPARC_64. */
15125 || reloc_type == 54; /* R_SPARC_UA64. */
15126 case EM_X86_64:
15127 case EM_L1OM:
15128 case EM_K1OM:
15129 return reloc_type == 1; /* R_X86_64_64. */
15130 case EM_S390_OLD:
15131 case EM_S390:
15132 return reloc_type == 22; /* R_S390_64. */
15133 case EM_TILEGX:
15134 return reloc_type == 1; /* R_TILEGX_64. */
15135 case EM_MIPS:
15136 return reloc_type == 18; /* R_MIPS_64. */
15137 case EM_KVX:
15138 return reloc_type == 3; /* R_KVX_64 */
15139 default:
15140 return false;
15144 /* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
15145 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
15147 static bool
15148 is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
15150 switch (filedata->file_header.e_machine)
15152 case EM_AARCH64:
15153 return reloc_type == 260; /* R_AARCH64_PREL64. */
15154 case EM_ALPHA:
15155 return reloc_type == 11; /* R_ALPHA_SREL64. */
15156 case EM_IA_64:
15157 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
15158 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
15159 case EM_PARISC:
15160 return reloc_type == 72; /* R_PARISC_PCREL64. */
15161 case EM_PPC64:
15162 return reloc_type == 44; /* R_PPC64_REL64. */
15163 case EM_SPARC32PLUS:
15164 case EM_SPARCV9:
15165 case EM_SPARC:
15166 return reloc_type == 46; /* R_SPARC_DISP64. */
15167 case EM_X86_64:
15168 case EM_L1OM:
15169 case EM_K1OM:
15170 return reloc_type == 24; /* R_X86_64_PC64. */
15171 case EM_S390_OLD:
15172 case EM_S390:
15173 return reloc_type == 23; /* R_S390_PC64. */
15174 case EM_TILEGX:
15175 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
15176 default:
15177 return false;
15181 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15182 a 24-bit absolute RELA relocation used in DWARF debug sections. */
15184 static bool
15185 is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15187 switch (filedata->file_header.e_machine)
15189 case EM_CYGNUS_MN10200:
15190 case EM_MN10200:
15191 return reloc_type == 4; /* R_MN10200_24. */
15192 case EM_FT32:
15193 return reloc_type == 5; /* R_FT32_20. */
15194 case EM_Z80:
15195 return reloc_type == 5; /* R_Z80_24. */
15196 default:
15197 return false;
15201 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15202 a 16-bit absolute RELA relocation used in DWARF debug sections. */
15204 static bool
15205 is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15207 /* Please keep this table alpha-sorted for ease of visual lookup. */
15208 switch (filedata->file_header.e_machine)
15210 case EM_ARC:
15211 case EM_ARC_COMPACT:
15212 case EM_ARC_COMPACT2:
15213 case EM_ARC_COMPACT3:
15214 case EM_ARC_COMPACT3_64:
15215 return reloc_type == 2; /* R_ARC_16. */
15216 case EM_ADAPTEVA_EPIPHANY:
15217 return reloc_type == 5;
15218 case EM_AVR_OLD:
15219 case EM_AVR:
15220 return reloc_type == 4; /* R_AVR_16. */
15221 case EM_CYGNUS_D10V:
15222 case EM_D10V:
15223 return reloc_type == 3; /* R_D10V_16. */
15224 case EM_FT32:
15225 return reloc_type == 2; /* R_FT32_16. */
15226 case EM_H8S:
15227 case EM_H8_300:
15228 case EM_H8_300H:
15229 return reloc_type == R_H8_DIR16;
15230 case EM_IP2K_OLD:
15231 case EM_IP2K:
15232 return reloc_type == 1; /* R_IP2K_16. */
15233 case EM_M32C_OLD:
15234 case EM_M32C:
15235 return reloc_type == 1; /* R_M32C_16 */
15236 case EM_CYGNUS_MN10200:
15237 case EM_MN10200:
15238 return reloc_type == 2; /* R_MN10200_16. */
15239 case EM_CYGNUS_MN10300:
15240 case EM_MN10300:
15241 return reloc_type == 2; /* R_MN10300_16. */
15242 case EM_KVX:
15243 return reloc_type == 1; /* R_KVX_16 */
15244 case EM_MSP430:
15245 if (uses_msp430x_relocs (filedata))
15246 return reloc_type == 2; /* R_MSP430_ABS16. */
15247 /* Fall through. */
15248 case EM_MSP430_OLD:
15249 return reloc_type == 5; /* R_MSP430_16_BYTE. */
15250 case EM_NDS32:
15251 return reloc_type == 19; /* R_NDS32_16_RELA. */
15252 case EM_ALTERA_NIOS2:
15253 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
15254 case EM_NIOS32:
15255 return reloc_type == 9; /* R_NIOS_16. */
15256 case EM_OR1K:
15257 return reloc_type == 2; /* R_OR1K_16. */
15258 case EM_RISCV:
15259 return reloc_type == 55; /* R_RISCV_SET16. */
15260 case EM_TI_PRU:
15261 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
15262 case EM_TI_C6000:
15263 return reloc_type == 2; /* R_C6000_ABS16. */
15264 case EM_VISIUM:
15265 return reloc_type == 2; /* R_VISIUM_16. */
15266 case EM_XGATE:
15267 return reloc_type == 3; /* R_XGATE_16. */
15268 case EM_Z80:
15269 return reloc_type == 4; /* R_Z80_16. */
15270 default:
15271 return false;
15275 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15276 a 8-bit absolute RELA relocation used in DWARF debug sections. */
15278 static bool
15279 is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15281 switch (filedata->file_header.e_machine)
15283 case EM_RISCV:
15284 return reloc_type == 54; /* R_RISCV_SET8. */
15285 case EM_Z80:
15286 return reloc_type == 1; /* R_Z80_8. */
15287 case EM_MICROBLAZE:
15288 return (reloc_type == 33 /* R_MICROBLAZE_32_NONE. */
15289 || reloc_type == 0 /* R_MICROBLAZE_NONE. */
15290 || reloc_type == 9 /* R_MICROBLAZE_64_NONE. */);
15291 default:
15292 return false;
15296 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15297 a 6-bit absolute RELA relocation used in DWARF debug sections. */
15299 static bool
15300 is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15302 switch (filedata->file_header.e_machine)
15304 case EM_RISCV:
15305 return reloc_type == 53; /* R_RISCV_SET6. */
15306 default:
15307 return false;
15311 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15312 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
15314 static bool
15315 is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15317 /* Please keep this table alpha-sorted for ease of visual lookup. */
15318 switch (filedata->file_header.e_machine)
15320 case EM_LOONGARCH:
15321 return reloc_type == 50; /* R_LARCH_ADD32. */
15322 case EM_RISCV:
15323 return reloc_type == 35; /* R_RISCV_ADD32. */
15324 default:
15325 return false;
15329 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15330 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
15332 static bool
15333 is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15335 /* Please keep this table alpha-sorted for ease of visual lookup. */
15336 switch (filedata->file_header.e_machine)
15338 case EM_LOONGARCH:
15339 return reloc_type == 55; /* R_LARCH_SUB32. */
15340 case EM_RISCV:
15341 return reloc_type == 39; /* R_RISCV_SUB32. */
15342 default:
15343 return false;
15347 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15348 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
15350 static bool
15351 is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15353 /* Please keep this table alpha-sorted for ease of visual lookup. */
15354 switch (filedata->file_header.e_machine)
15356 case EM_LOONGARCH:
15357 return reloc_type == 51; /* R_LARCH_ADD64. */
15358 case EM_RISCV:
15359 return reloc_type == 36; /* R_RISCV_ADD64. */
15360 default:
15361 return false;
15365 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15366 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
15368 static bool
15369 is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15371 /* Please keep this table alpha-sorted for ease of visual lookup. */
15372 switch (filedata->file_header.e_machine)
15374 case EM_LOONGARCH:
15375 return reloc_type == 56; /* R_LARCH_SUB64. */
15376 case EM_RISCV:
15377 return reloc_type == 40; /* R_RISCV_SUB64. */
15378 default:
15379 return false;
15383 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15384 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
15386 static bool
15387 is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15389 /* Please keep this table alpha-sorted for ease of visual lookup. */
15390 switch (filedata->file_header.e_machine)
15392 case EM_LOONGARCH:
15393 return reloc_type == 48; /* R_LARCH_ADD16. */
15394 case EM_RISCV:
15395 return reloc_type == 34; /* R_RISCV_ADD16. */
15396 default:
15397 return false;
15401 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15402 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
15404 static bool
15405 is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15407 /* Please keep this table alpha-sorted for ease of visual lookup. */
15408 switch (filedata->file_header.e_machine)
15410 case EM_LOONGARCH:
15411 return reloc_type == 53; /* R_LARCH_SUB16. */
15412 case EM_RISCV:
15413 return reloc_type == 38; /* R_RISCV_SUB16. */
15414 default:
15415 return false;
15419 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15420 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
15422 static bool
15423 is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15425 /* Please keep this table alpha-sorted for ease of visual lookup. */
15426 switch (filedata->file_header.e_machine)
15428 case EM_LOONGARCH:
15429 return reloc_type == 47; /* R_LARCH_ADD8. */
15430 case EM_RISCV:
15431 return reloc_type == 33; /* R_RISCV_ADD8. */
15432 default:
15433 return false;
15437 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15438 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
15440 static bool
15441 is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15443 /* Please keep this table alpha-sorted for ease of visual lookup. */
15444 switch (filedata->file_header.e_machine)
15446 case EM_LOONGARCH:
15447 return reloc_type == 52; /* R_LARCH_SUB8. */
15448 case EM_RISCV:
15449 return reloc_type == 37; /* R_RISCV_SUB8. */
15450 default:
15451 return false;
15455 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15456 a 6-bit inplace add RELA relocation used in DWARF debug sections. */
15458 static bool
15459 is_6bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15461 switch (filedata->file_header.e_machine)
15463 case EM_LOONGARCH:
15464 return reloc_type == 105; /* R_LARCH_ADD6. */
15465 default:
15466 return false;
15470 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15471 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
15473 static bool
15474 is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15476 switch (filedata->file_header.e_machine)
15478 case EM_LOONGARCH:
15479 return reloc_type == 106; /* R_LARCH_SUB6. */
15480 case EM_RISCV:
15481 return reloc_type == 52; /* R_RISCV_SUB6. */
15482 default:
15483 return false;
15487 /* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
15488 relocation entries (possibly formerly used for SHT_GROUP sections). */
15490 static bool
15491 is_none_reloc (Filedata * filedata, unsigned int reloc_type)
15493 switch (filedata->file_header.e_machine)
15495 case EM_386: /* R_386_NONE. */
15496 case EM_68K: /* R_68K_NONE. */
15497 case EM_ADAPTEVA_EPIPHANY:
15498 case EM_ALPHA: /* R_ALPHA_NONE. */
15499 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
15500 case EM_ARC: /* R_ARC_NONE. */
15501 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
15502 case EM_ARC_COMPACT: /* R_ARC_NONE. */
15503 case EM_ARC_COMPACT3: /* R_ARC_NONE. */
15504 case EM_ARC_COMPACT3_64: /* R_ARC_NONE. */
15505 case EM_ARM: /* R_ARM_NONE. */
15506 case EM_CRIS: /* R_CRIS_NONE. */
15507 case EM_FT32: /* R_FT32_NONE. */
15508 case EM_IA_64: /* R_IA64_NONE. */
15509 case EM_K1OM: /* R_X86_64_NONE. */
15510 case EM_KVX: /* R_KVX_NONE. */
15511 case EM_L1OM: /* R_X86_64_NONE. */
15512 case EM_M32R: /* R_M32R_NONE. */
15513 case EM_MIPS: /* R_MIPS_NONE. */
15514 case EM_MN10300: /* R_MN10300_NONE. */
15515 case EM_MOXIE: /* R_MOXIE_NONE. */
15516 case EM_NIOS32: /* R_NIOS_NONE. */
15517 case EM_OR1K: /* R_OR1K_NONE. */
15518 case EM_PARISC: /* R_PARISC_NONE. */
15519 case EM_PPC64: /* R_PPC64_NONE. */
15520 case EM_PPC: /* R_PPC_NONE. */
15521 case EM_RISCV: /* R_RISCV_NONE. */
15522 case EM_S390: /* R_390_NONE. */
15523 case EM_S390_OLD:
15524 case EM_SH: /* R_SH_NONE. */
15525 case EM_SPARC32PLUS:
15526 case EM_SPARC: /* R_SPARC_NONE. */
15527 case EM_SPARCV9:
15528 case EM_TILEGX: /* R_TILEGX_NONE. */
15529 case EM_TILEPRO: /* R_TILEPRO_NONE. */
15530 case EM_TI_C6000:/* R_C6000_NONE. */
15531 case EM_X86_64: /* R_X86_64_NONE. */
15532 case EM_Z80: /* R_Z80_NONE. */
15533 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
15534 return reloc_type == 0;
15536 case EM_AARCH64:
15537 return reloc_type == 0 || reloc_type == 256;
15538 case EM_AVR_OLD:
15539 case EM_AVR:
15540 return (reloc_type == 0 /* R_AVR_NONE. */
15541 || reloc_type == 30 /* R_AVR_DIFF8. */
15542 || reloc_type == 31 /* R_AVR_DIFF16. */
15543 || reloc_type == 32 /* R_AVR_DIFF32. */);
15544 case EM_METAG:
15545 return reloc_type == 3; /* R_METAG_NONE. */
15546 case EM_NDS32:
15547 return (reloc_type == 0 /* R_NDS32_NONE. */
15548 || reloc_type == 205 /* R_NDS32_DIFF8. */
15549 || reloc_type == 206 /* R_NDS32_DIFF16. */
15550 || reloc_type == 207 /* R_NDS32_DIFF32. */
15551 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
15552 case EM_TI_PRU:
15553 return (reloc_type == 0 /* R_PRU_NONE. */
15554 || reloc_type == 65 /* R_PRU_DIFF8. */
15555 || reloc_type == 66 /* R_PRU_DIFF16. */
15556 || reloc_type == 67 /* R_PRU_DIFF32. */);
15557 case EM_XTENSA_OLD:
15558 case EM_XTENSA:
15559 return (reloc_type == 0 /* R_XTENSA_NONE. */
15560 || reloc_type == 17 /* R_XTENSA_DIFF8. */
15561 || reloc_type == 18 /* R_XTENSA_DIFF16. */
15562 || reloc_type == 19 /* R_XTENSA_DIFF32. */
15563 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
15564 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
15565 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
15566 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
15567 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
15568 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
15570 return false;
15573 /* Returns TRUE if there is a relocation against
15574 section NAME at OFFSET bytes. */
15576 bool
15577 reloc_at (struct dwarf_section * dsec, uint64_t offset)
15579 Elf_Internal_Rela * relocs;
15580 Elf_Internal_Rela * rp;
15582 if (dsec == NULL || dsec->reloc_info == NULL)
15583 return false;
15585 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
15587 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
15588 if (rp->r_offset == offset)
15589 return true;
15591 return false;
15594 /* Apply relocations to a section.
15595 Returns TRUE upon success, FALSE otherwise.
15596 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
15597 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
15598 will be set to the number of relocs loaded.
15600 Note: So far support has been added only for those relocations
15601 which can be found in debug sections. FIXME: Add support for
15602 more relocations ? */
15604 static bool
15605 apply_relocations (Filedata *filedata,
15606 const Elf_Internal_Shdr *section,
15607 unsigned char *start,
15608 size_t size,
15609 void **relocs_return,
15610 uint64_t *num_relocs_return)
15612 Elf_Internal_Shdr * relsec;
15613 unsigned char * end = start + size;
15615 if (relocs_return != NULL)
15617 * (Elf_Internal_Rela **) relocs_return = NULL;
15618 * num_relocs_return = 0;
15621 if (filedata->file_header.e_type != ET_REL)
15622 /* No relocs to apply. */
15623 return true;
15625 /* Find the reloc section associated with the section. */
15626 for (relsec = filedata->section_headers;
15627 relsec < filedata->section_headers + filedata->file_header.e_shnum;
15628 ++relsec)
15630 bool is_rela;
15631 uint64_t num_relocs;
15632 Elf_Internal_Rela * relocs;
15633 Elf_Internal_Rela * rp;
15634 Elf_Internal_Shdr * symsec;
15635 Elf_Internal_Sym * symtab;
15636 uint64_t num_syms;
15637 Elf_Internal_Sym * sym;
15639 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
15640 || relsec->sh_info >= filedata->file_header.e_shnum
15641 || filedata->section_headers + relsec->sh_info != section
15642 || relsec->sh_size == 0
15643 || relsec->sh_link >= filedata->file_header.e_shnum)
15644 continue;
15646 symsec = filedata->section_headers + relsec->sh_link;
15647 if (symsec->sh_type != SHT_SYMTAB
15648 && symsec->sh_type != SHT_DYNSYM)
15649 return false;
15651 is_rela = relsec->sh_type == SHT_RELA;
15653 if (is_rela)
15655 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
15656 relsec->sh_size, & relocs, & num_relocs))
15657 return false;
15659 else
15661 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
15662 relsec->sh_size, & relocs, & num_relocs))
15663 return false;
15666 /* SH uses RELA but uses in place value instead of the addend field. */
15667 if (filedata->file_header.e_machine == EM_SH)
15668 is_rela = false;
15670 symtab = get_elf_symbols (filedata, symsec, & num_syms);
15672 for (rp = relocs; rp < relocs + num_relocs; ++rp)
15674 uint64_t addend;
15675 unsigned int reloc_type;
15676 unsigned int reloc_size;
15677 bool reloc_inplace = false;
15678 bool reloc_subtract = false;
15679 unsigned char *rloc;
15680 uint64_t sym_index;
15682 reloc_type = get_reloc_type (filedata, rp->r_info);
15684 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
15685 continue;
15686 else if (is_none_reloc (filedata, reloc_type))
15687 continue;
15688 else if (is_32bit_abs_reloc (filedata, reloc_type)
15689 || is_32bit_pcrel_reloc (filedata, reloc_type))
15690 reloc_size = 4;
15691 else if (is_64bit_abs_reloc (filedata, reloc_type)
15692 || is_64bit_pcrel_reloc (filedata, reloc_type))
15693 reloc_size = 8;
15694 else if (is_24bit_abs_reloc (filedata, reloc_type))
15695 reloc_size = 3;
15696 else if (is_16bit_abs_reloc (filedata, reloc_type))
15697 reloc_size = 2;
15698 else if (is_8bit_abs_reloc (filedata, reloc_type)
15699 || is_6bit_abs_reloc (filedata, reloc_type))
15700 reloc_size = 1;
15701 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
15702 reloc_type))
15703 || is_32bit_inplace_add_reloc (filedata, reloc_type))
15705 reloc_size = 4;
15706 reloc_inplace = true;
15708 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
15709 reloc_type))
15710 || is_64bit_inplace_add_reloc (filedata, reloc_type))
15712 reloc_size = 8;
15713 reloc_inplace = true;
15715 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
15716 reloc_type))
15717 || is_16bit_inplace_add_reloc (filedata, reloc_type))
15719 reloc_size = 2;
15720 reloc_inplace = true;
15722 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
15723 reloc_type))
15724 || is_8bit_inplace_add_reloc (filedata, reloc_type))
15726 reloc_size = 1;
15727 reloc_inplace = true;
15729 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
15730 reloc_type))
15731 || is_6bit_inplace_add_reloc (filedata, reloc_type))
15733 reloc_size = 1;
15734 reloc_inplace = true;
15736 else
15738 static unsigned int prev_reloc = 0;
15740 if (reloc_type != prev_reloc)
15741 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
15742 reloc_type, printable_section_name (filedata, section));
15743 prev_reloc = reloc_type;
15744 continue;
15747 rloc = start + rp->r_offset;
15748 if (!IN_RANGE (start, end, rloc, reloc_size))
15750 warn (_("skipping invalid relocation offset %#" PRIx64
15751 " in section %s\n"),
15752 rp->r_offset,
15753 printable_section_name (filedata, section));
15754 continue;
15757 sym_index = get_reloc_symindex (rp->r_info);
15758 if (sym_index >= num_syms)
15760 warn (_("skipping invalid relocation symbol index %#" PRIx64
15761 " in section %s\n"),
15762 sym_index, printable_section_name (filedata, section));
15763 continue;
15765 sym = symtab + sym_index;
15767 /* If the reloc has a symbol associated with it,
15768 make sure that it is of an appropriate type.
15770 Relocations against symbols without type can happen.
15771 Gcc -feliminate-dwarf2-dups may generate symbols
15772 without type for debug info.
15774 Icc generates relocations against function symbols
15775 instead of local labels.
15777 Relocations against object symbols can happen, eg when
15778 referencing a global array. For an example of this see
15779 the _clz.o binary in libgcc.a. */
15780 if (sym != symtab
15781 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
15782 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
15784 warn (_("skipping unexpected symbol type %s in section %s relocation %tu\n"),
15785 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
15786 printable_section_name (filedata, relsec),
15787 rp - relocs);
15788 continue;
15791 addend = 0;
15792 if (is_rela)
15793 addend += rp->r_addend;
15794 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
15795 partial_inplace. */
15796 if (!is_rela
15797 || (filedata->file_header.e_machine == EM_XTENSA
15798 && reloc_type == 1)
15799 || ((filedata->file_header.e_machine == EM_PJ
15800 || filedata->file_header.e_machine == EM_PJ_OLD)
15801 && reloc_type == 1)
15802 || ((filedata->file_header.e_machine == EM_D30V
15803 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
15804 && reloc_type == 12)
15805 || reloc_inplace)
15807 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
15808 addend += byte_get (rloc, reloc_size) & 0x3f;
15809 else
15810 addend += byte_get (rloc, reloc_size);
15813 if (is_32bit_pcrel_reloc (filedata, reloc_type)
15814 || is_64bit_pcrel_reloc (filedata, reloc_type))
15816 /* On HPPA, all pc-relative relocations are biased by 8. */
15817 if (filedata->file_header.e_machine == EM_PARISC)
15818 addend -= 8;
15819 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
15820 reloc_size);
15822 else if (is_6bit_abs_reloc (filedata, reloc_type)
15823 || is_6bit_inplace_sub_reloc (filedata, reloc_type)
15824 || is_6bit_inplace_add_reloc (filedata, reloc_type))
15826 if (reloc_subtract)
15827 addend -= sym->st_value;
15828 else
15829 addend += sym->st_value;
15830 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
15831 byte_put (rloc, addend, reloc_size);
15833 else if (reloc_subtract)
15834 byte_put (rloc, addend - sym->st_value, reloc_size);
15835 else
15836 byte_put (rloc, addend + sym->st_value, reloc_size);
15839 free (symtab);
15840 /* Let the target specific reloc processing code know that
15841 we have finished with these relocs. */
15842 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
15844 if (relocs_return)
15846 * (Elf_Internal_Rela **) relocs_return = relocs;
15847 * num_relocs_return = num_relocs;
15849 else
15850 free (relocs);
15852 break;
15855 return true;
15858 #ifdef SUPPORT_DISASSEMBLY
15859 static bool
15860 disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
15862 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
15864 /* FIXME: XXX -- to be done --- XXX */
15866 return true;
15868 #endif
15870 /* Reads in the contents of SECTION from FILE, returning a pointer
15871 to a malloc'ed buffer or NULL if something went wrong. */
15873 static char *
15874 get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
15876 uint64_t num_bytes = section->sh_size;
15878 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15880 printf (_("Section '%s' has no data to dump.\n"),
15881 printable_section_name (filedata, section));
15882 return NULL;
15885 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
15886 _("section contents"));
15889 /* Uncompresses a section that was compressed using zlib/zstd, in place. */
15891 static bool
15892 uncompress_section_contents (bool is_zstd,
15893 unsigned char ** buffer,
15894 uint64_t uncompressed_size,
15895 uint64_t * size,
15896 uint64_t file_size)
15898 uint64_t compressed_size = *size;
15899 unsigned char *compressed_buffer = *buffer;
15900 unsigned char *uncompressed_buffer = NULL;
15901 z_stream strm;
15902 int rc;
15904 /* Similar to _bfd_section_size_insane() in the BFD library we expect an
15905 upper limit of ~10x compression. Any compression larger than that is
15906 thought to be due to fuzzing of the compression header. */
15907 if (uncompressed_size > file_size * 10)
15909 error (_("Uncompressed section size is suspiciously large: 0x%" PRIu64 "\n"),
15910 uncompressed_size);
15911 goto fail;
15914 uncompressed_buffer = xmalloc (uncompressed_size);
15916 if (is_zstd)
15918 #ifdef HAVE_ZSTD
15919 size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size,
15920 compressed_buffer, compressed_size);
15921 if (ZSTD_isError (ret))
15922 goto fail;
15923 #endif
15925 else
15927 /* It is possible the section consists of several compressed
15928 buffers concatenated together, so we uncompress in a loop. */
15929 /* PR 18313: The state field in the z_stream structure is supposed
15930 to be invisible to the user (ie us), but some compilers will
15931 still complain about it being used without initialisation. So
15932 we first zero the entire z_stream structure and then set the fields
15933 that we need. */
15934 memset (&strm, 0, sizeof strm);
15935 strm.avail_in = compressed_size;
15936 strm.next_in = (Bytef *)compressed_buffer;
15937 strm.avail_out = uncompressed_size;
15939 rc = inflateInit (&strm);
15940 while (strm.avail_in > 0)
15942 if (rc != Z_OK)
15943 break;
15944 strm.next_out = ((Bytef *)uncompressed_buffer
15945 + (uncompressed_size - strm.avail_out));
15946 rc = inflate (&strm, Z_FINISH);
15947 if (rc != Z_STREAM_END)
15948 break;
15949 rc = inflateReset (&strm);
15951 if (inflateEnd (&strm) != Z_OK || rc != Z_OK || strm.avail_out != 0)
15952 goto fail;
15955 *buffer = uncompressed_buffer;
15956 *size = uncompressed_size;
15957 return true;
15959 fail:
15960 free (uncompressed_buffer);
15961 /* Indicate decompression failure. */
15962 *buffer = NULL;
15963 return false;
15966 static uint64_t
15967 maybe_expand_or_relocate_section (Elf_Internal_Shdr * section,
15968 Filedata * filedata,
15969 unsigned char ** start_ptr,
15970 bool relocate)
15972 uint64_t section_size = section->sh_size;
15973 unsigned char * start = * start_ptr;
15975 if (decompress_dumps)
15977 uint64_t new_size = section_size;
15978 uint64_t uncompressed_size = 0;
15979 bool is_zstd = false;
15981 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15983 Elf_Internal_Chdr chdr;
15984 unsigned int compression_header_size
15985 = get_compression_header (& chdr, start, section_size);
15987 if (compression_header_size == 0)
15988 /* An error message will have already been generated
15989 by get_compression_header. */
15990 return (uint64_t) -1;
15992 if (chdr.ch_type == ch_compress_zlib)
15994 #ifdef HAVE_ZSTD
15995 else if (chdr.ch_type == ch_compress_zstd)
15996 is_zstd = true;
15997 #endif
15998 else
16000 warn (_("section '%s' has unsupported compress type: %d\n"),
16001 printable_section_name (filedata, section), chdr.ch_type);
16002 return (uint64_t) -1;
16005 uncompressed_size = chdr.ch_size;
16006 start += compression_header_size;
16007 new_size -= compression_header_size;
16009 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
16011 /* Read the zlib header. In this case, it should be "ZLIB"
16012 followed by the uncompressed section size, 8 bytes in
16013 big-endian order. */
16014 uncompressed_size = start[4]; uncompressed_size <<= 8;
16015 uncompressed_size += start[5]; uncompressed_size <<= 8;
16016 uncompressed_size += start[6]; uncompressed_size <<= 8;
16017 uncompressed_size += start[7]; uncompressed_size <<= 8;
16018 uncompressed_size += start[8]; uncompressed_size <<= 8;
16019 uncompressed_size += start[9]; uncompressed_size <<= 8;
16020 uncompressed_size += start[10]; uncompressed_size <<= 8;
16021 uncompressed_size += start[11];
16022 start += 12;
16023 new_size -= 12;
16026 if (uncompressed_size)
16028 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
16029 &new_size, filedata->file_size))
16030 section_size = new_size;
16031 else
16033 error (_("Unable to decompress section %s\n"),
16034 printable_section_name (filedata, section));
16035 return (uint64_t) -1;
16038 else
16039 start = * start_ptr;
16041 else if (((section->sh_flags & SHF_COMPRESSED) != 0)
16042 || (section_size > 12 && streq ((char *) start, "ZLIB")))
16044 printf (_(" NOTE: This section is compressed, but its contents have NOT been expanded for this dump.\n"));
16047 if (relocate)
16049 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
16050 return (uint64_t) -1;
16052 else
16054 Elf_Internal_Shdr *relsec;
16056 /* If the section being dumped has relocations against it the user might
16057 be expecting these relocations to have been applied. Check for this
16058 case and issue a warning message in order to avoid confusion.
16059 FIXME: Maybe we ought to have an option that dumps a section with
16060 relocs applied ? */
16061 for (relsec = filedata->section_headers;
16062 relsec < filedata->section_headers + filedata->file_header.e_shnum;
16063 ++relsec)
16065 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
16066 || relsec->sh_info >= filedata->file_header.e_shnum
16067 || filedata->section_headers + relsec->sh_info != section
16068 || relsec->sh_size == 0
16069 || relsec->sh_link >= filedata->file_header.e_shnum)
16070 continue;
16072 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
16073 break;
16077 * start_ptr = start;
16078 return section_size;
16081 static bool
16082 dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
16084 uint64_t num_bytes;
16085 unsigned char *data;
16086 unsigned char *end;
16087 unsigned char *real_start;
16088 unsigned char *start;
16089 bool some_strings_shown;
16091 real_start = start = (unsigned char *) get_section_contents (section, filedata);
16092 if (start == NULL)
16093 /* PR 21820: Do not fail if the section was empty. */
16094 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
16096 num_bytes = section->sh_size;
16098 if (filedata->is_separate)
16099 printf (_("\nString dump of section '%s' in linked file %s:\n"),
16100 printable_section_name (filedata, section),
16101 filedata->file_name);
16102 else
16103 printf (_("\nString dump of section '%s':\n"),
16104 printable_section_name (filedata, section));
16106 num_bytes = maybe_expand_or_relocate_section (section, filedata, & start, false);
16107 if (num_bytes == (uint64_t) -1)
16108 goto error_out;
16110 data = start;
16111 end = start + num_bytes;
16112 some_strings_shown = false;
16114 #ifdef HAVE_MBSTATE_T
16115 mbstate_t state;
16116 /* Initialise the multibyte conversion state. */
16117 memset (& state, 0, sizeof (state));
16118 #endif
16120 bool continuing = false;
16122 while (data < end)
16124 while (!ISPRINT (* data))
16125 if (++ data >= end)
16126 break;
16128 if (data < end)
16130 size_t maxlen = end - data;
16132 if (continuing)
16134 printf (" ");
16135 continuing = false;
16137 else
16139 printf (" [%6tx] ", data - start);
16142 if (maxlen > 0)
16144 char c = 0;
16146 while (maxlen)
16148 c = *data++;
16150 if (c == 0)
16151 break;
16153 /* PR 25543: Treat new-lines as string-ending characters. */
16154 if (c == '\n')
16156 printf ("\\n\n");
16157 if (*data != 0)
16158 continuing = true;
16159 break;
16162 /* Do not print control characters directly as they can affect terminal
16163 settings. Such characters usually appear in the names generated
16164 by the assembler for local labels. */
16165 if (ISCNTRL (c))
16167 printf ("^%c", c + 0x40);
16169 else if (ISPRINT (c))
16171 putchar (c);
16173 else
16175 size_t n;
16176 #ifdef HAVE_MBSTATE_T
16177 wchar_t w;
16178 #endif
16179 /* Let printf do the hard work of displaying multibyte characters. */
16180 printf ("%.1s", data - 1);
16181 #ifdef HAVE_MBSTATE_T
16182 /* Try to find out how many bytes made up the character that was
16183 just printed. Advance the symbol pointer past the bytes that
16184 were displayed. */
16185 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
16186 #else
16187 n = 1;
16188 #endif
16189 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
16190 data += (n - 1);
16194 if (c != '\n')
16195 putchar ('\n');
16197 else
16199 printf (_("<corrupt>\n"));
16200 data = end;
16202 some_strings_shown = true;
16206 if (! some_strings_shown)
16207 printf (_(" No strings found in this section."));
16209 free (real_start);
16211 putchar ('\n');
16212 return true;
16214 error_out:
16215 free (real_start);
16216 return false;
16219 static bool
16220 dump_section_as_bytes (Elf_Internal_Shdr *section,
16221 Filedata *filedata,
16222 bool relocate)
16224 size_t bytes;
16225 uint64_t section_size;
16226 uint64_t addr;
16227 unsigned char *data;
16228 unsigned char *real_start;
16229 unsigned char *start;
16231 real_start = start = (unsigned char *) get_section_contents (section, filedata);
16232 if (start == NULL)
16233 /* PR 21820: Do not fail if the section was empty. */
16234 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
16236 section_size = section->sh_size;
16238 if (filedata->is_separate)
16239 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
16240 printable_section_name (filedata, section),
16241 filedata->file_name);
16242 else
16243 printf (_("\nHex dump of section '%s':\n"),
16244 printable_section_name (filedata, section));
16246 section_size = maybe_expand_or_relocate_section (section, filedata, & start, relocate);
16247 if (section_size == (uint64_t) -1)
16248 goto error_out;
16250 addr = section->sh_addr;
16251 bytes = section_size;
16252 data = start;
16254 while (bytes)
16256 int j;
16257 int k;
16258 int lbytes;
16260 lbytes = (bytes > 16 ? 16 : bytes);
16262 printf (" 0x%8.8" PRIx64 " ", addr);
16264 for (j = 0; j < 16; j++)
16266 if (j < lbytes)
16267 printf ("%2.2x", data[j]);
16268 else
16269 printf (" ");
16271 if ((j & 3) == 3)
16272 printf (" ");
16275 for (j = 0; j < lbytes; j++)
16277 k = data[j];
16278 if (k >= ' ' && k < 0x7f)
16279 printf ("%c", k);
16280 else
16281 printf (".");
16284 putchar ('\n');
16286 data += lbytes;
16287 addr += lbytes;
16288 bytes -= lbytes;
16291 free (real_start);
16293 putchar ('\n');
16294 return true;
16296 error_out:
16297 free (real_start);
16298 return false;
16301 #ifdef ENABLE_LIBCTF
16302 static ctf_sect_t *
16303 shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
16305 buf->cts_name = printable_section_name (filedata, shdr);
16306 buf->cts_size = shdr->sh_size;
16307 buf->cts_entsize = shdr->sh_entsize;
16309 return buf;
16312 /* Formatting callback function passed to ctf_dump. Returns either the pointer
16313 it is passed, or a pointer to newly-allocated storage, in which case
16314 dump_ctf() will free it when it no longer needs it. */
16316 static char *
16317 dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
16318 char *s, void *arg)
16320 const char *blanks = arg;
16321 char *new_s;
16323 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
16324 return s;
16325 return new_s;
16328 /* Dump CTF errors/warnings. */
16329 static void
16330 dump_ctf_errs (ctf_dict_t *fp)
16332 ctf_next_t *it = NULL;
16333 char *errtext;
16334 int is_warning;
16335 int err;
16337 /* Dump accumulated errors and warnings. */
16338 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
16340 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
16341 errtext);
16342 free (errtext);
16344 if (err != ECTF_NEXT_END)
16345 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
16348 /* Dump one CTF archive member. */
16350 static void
16351 dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
16352 size_t member)
16354 const char *things[] = {"Header", "Labels", "Data objects",
16355 "Function objects", "Variables", "Types", "Strings",
16356 ""};
16357 const char **thing;
16358 size_t i;
16360 /* Don't print out the name of the default-named archive member if it appears
16361 first in the list. The name .ctf appears everywhere, even for things that
16362 aren't really archives, so printing it out is liable to be confusing; also,
16363 the common case by far is for only one archive member to exist, and hiding
16364 it in that case seems worthwhile. */
16366 if (strcmp (name, ".ctf") != 0 || member != 0)
16367 printf (_("\nCTF archive member: %s:\n"), name);
16369 if (ctf_parent_name (ctf) != NULL)
16370 ctf_import (ctf, parent);
16372 for (i = 0, thing = things; *thing[0]; thing++, i++)
16374 ctf_dump_state_t *s = NULL;
16375 char *item;
16377 printf ("\n %s:\n", *thing);
16378 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
16379 (void *) " ")) != NULL)
16381 printf ("%s\n", item);
16382 free (item);
16385 if (ctf_errno (ctf))
16387 error (_("Iteration failed: %s, %s\n"), *thing,
16388 ctf_errmsg (ctf_errno (ctf)));
16389 break;
16393 dump_ctf_errs (ctf);
16396 static bool
16397 dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
16399 Elf_Internal_Shdr * symtab_sec = NULL;
16400 Elf_Internal_Shdr * strtab_sec = NULL;
16401 void * data = NULL;
16402 void * symdata = NULL;
16403 void * strdata = NULL;
16404 ctf_sect_t ctfsect, symsect, strsect;
16405 ctf_sect_t * symsectp = NULL;
16406 ctf_sect_t * strsectp = NULL;
16407 ctf_archive_t * ctfa = NULL;
16408 ctf_dict_t * parent = NULL;
16409 ctf_dict_t * fp;
16411 ctf_next_t *i = NULL;
16412 const char *name;
16413 size_t member = 0;
16414 int err;
16415 bool ret = false;
16417 shdr_to_ctf_sect (&ctfsect, section, filedata);
16418 data = get_section_contents (section, filedata);
16419 ctfsect.cts_data = data;
16421 if (!dump_ctf_symtab_name)
16422 dump_ctf_symtab_name = strdup (".dynsym");
16424 if (!dump_ctf_strtab_name)
16425 dump_ctf_strtab_name = strdup (".dynstr");
16427 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
16429 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
16431 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
16432 goto fail;
16434 if ((symdata = (void *) get_data (NULL, filedata,
16435 symtab_sec->sh_offset, 1,
16436 symtab_sec->sh_size,
16437 _("symbols"))) == NULL)
16438 goto fail;
16439 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
16440 symsect.cts_data = symdata;
16443 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
16445 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
16447 error (_("No string table section named %s\n"),
16448 dump_ctf_strtab_name);
16449 goto fail;
16451 if ((strdata = (void *) get_data (NULL, filedata,
16452 strtab_sec->sh_offset, 1,
16453 strtab_sec->sh_size,
16454 _("strings"))) == NULL)
16455 goto fail;
16456 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
16457 strsect.cts_data = strdata;
16460 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
16461 libctf papers over the difference, so we can pretend it is always an
16462 archive. */
16464 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
16466 dump_ctf_errs (NULL);
16467 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16468 goto fail;
16471 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
16472 != ELFDATA2MSB);
16474 /* Preload the parent dict, since it will need to be imported into every
16475 child in turn. */
16476 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
16478 dump_ctf_errs (NULL);
16479 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16480 goto fail;
16483 ret = true;
16485 if (filedata->is_separate)
16486 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
16487 printable_section_name (filedata, section),
16488 filedata->file_name);
16489 else
16490 printf (_("\nDump of CTF section '%s':\n"),
16491 printable_section_name (filedata, section));
16493 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
16494 dump_ctf_archive_member (fp, name, parent, member++);
16495 if (err != ECTF_NEXT_END)
16497 dump_ctf_errs (NULL);
16498 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
16499 ret = false;
16502 fail:
16503 ctf_dict_close (parent);
16504 ctf_close (ctfa);
16505 free (data);
16506 free (symdata);
16507 free (strdata);
16508 return ret;
16510 #endif
16512 static bool
16513 dump_section_as_sframe (Elf_Internal_Shdr * section, Filedata * filedata)
16515 void * data = NULL;
16516 sframe_decoder_ctx *sfd_ctx = NULL;
16517 const char *print_name = printable_section_name (filedata, section);
16519 bool ret = true;
16520 size_t sf_size;
16521 int err = 0;
16523 if (strcmp (print_name, "") == 0)
16525 error (_("Section name must be provided \n"));
16526 ret = false;
16527 return ret;
16530 data = get_section_contents (section, filedata);
16531 sf_size = section->sh_size;
16532 /* Decode the contents of the section. */
16533 sfd_ctx = sframe_decode ((const char*)data, sf_size, &err);
16534 if (!sfd_ctx)
16536 ret = false;
16537 error (_("SFrame decode failure: %s\n"), sframe_errmsg (err));
16538 goto fail;
16541 printf (_("Contents of the SFrame section %s:"), print_name);
16542 /* Dump the contents as text. */
16543 dump_sframe (sfd_ctx, section->sh_addr);
16545 fail:
16546 free (data);
16547 return ret;
16550 static bool
16551 load_specific_debug_section (enum dwarf_section_display_enum debug,
16552 const Elf_Internal_Shdr * sec,
16553 void * data)
16555 struct dwarf_section * section = &debug_displays [debug].section;
16556 char buf [64];
16557 Filedata * filedata = (Filedata *) data;
16559 if (section->start != NULL)
16561 /* If it is already loaded, do nothing. */
16562 if (streq (section->filename, filedata->file_name))
16563 return true;
16564 free (section->start);
16567 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
16568 section->address = sec->sh_addr;
16569 section->filename = filedata->file_name;
16570 section->start = (unsigned char *) get_data (NULL, filedata,
16571 sec->sh_offset, 1,
16572 sec->sh_size, buf);
16573 if (section->start == NULL)
16574 section->size = 0;
16575 else
16577 unsigned char *start = section->start;
16578 uint64_t size = sec->sh_size;
16579 uint64_t uncompressed_size = 0;
16580 bool is_zstd = false;
16582 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
16584 Elf_Internal_Chdr chdr;
16585 unsigned int compression_header_size;
16587 if (size < (is_32bit_elf
16588 ? sizeof (Elf32_External_Chdr)
16589 : sizeof (Elf64_External_Chdr)))
16591 warn (_("compressed section %s is too small to contain a compression header\n"),
16592 section->name);
16593 return false;
16596 compression_header_size = get_compression_header (&chdr, start, size);
16597 if (compression_header_size == 0)
16598 /* An error message will have already been generated
16599 by get_compression_header. */
16600 return false;
16602 if (chdr.ch_type == ch_compress_zlib)
16604 #ifdef HAVE_ZSTD
16605 else if (chdr.ch_type == ch_compress_zstd)
16606 is_zstd = true;
16607 #endif
16608 else
16610 warn (_("section '%s' has unsupported compress type: %d\n"),
16611 section->name, chdr.ch_type);
16612 return false;
16614 uncompressed_size = chdr.ch_size;
16615 start += compression_header_size;
16616 size -= compression_header_size;
16618 else if (size > 12 && streq ((char *) start, "ZLIB"))
16620 /* Read the zlib header. In this case, it should be "ZLIB"
16621 followed by the uncompressed section size, 8 bytes in
16622 big-endian order. */
16623 uncompressed_size = start[4]; uncompressed_size <<= 8;
16624 uncompressed_size += start[5]; uncompressed_size <<= 8;
16625 uncompressed_size += start[6]; uncompressed_size <<= 8;
16626 uncompressed_size += start[7]; uncompressed_size <<= 8;
16627 uncompressed_size += start[8]; uncompressed_size <<= 8;
16628 uncompressed_size += start[9]; uncompressed_size <<= 8;
16629 uncompressed_size += start[10]; uncompressed_size <<= 8;
16630 uncompressed_size += start[11];
16631 start += 12;
16632 size -= 12;
16635 if (uncompressed_size)
16637 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
16638 &size, filedata->file_size))
16640 /* Free the compressed buffer, update the section buffer
16641 and the section size if uncompress is successful. */
16642 free (section->start);
16643 section->start = start;
16645 else
16647 error (_("Unable to decompress section %s\n"),
16648 printable_section_name (filedata, sec));
16649 return false;
16653 section->size = size;
16656 if (section->start == NULL)
16657 return false;
16659 if (debug_displays [debug].relocate)
16661 if (! apply_relocations (filedata, sec, section->start, section->size,
16662 & section->reloc_info, & section->num_relocs))
16663 return false;
16665 else
16667 section->reloc_info = NULL;
16668 section->num_relocs = 0;
16671 return true;
16674 #if HAVE_LIBDEBUGINFOD
16675 /* Return a hex string representation of the build-id. */
16676 unsigned char *
16677 get_build_id (void * data)
16679 Filedata * filedata = (Filedata *) data;
16680 Elf_Internal_Shdr * shdr;
16681 size_t i;
16683 /* Iterate through notes to find note.gnu.build-id.
16684 FIXME: Only the first note in any note section is examined. */
16685 for (i = 0, shdr = filedata->section_headers;
16686 i < filedata->file_header.e_shnum && shdr != NULL;
16687 i++, shdr++)
16689 if (shdr->sh_type != SHT_NOTE)
16690 continue;
16692 char * next;
16693 char * end;
16694 size_t data_remaining;
16695 size_t min_notesz;
16696 Elf_External_Note * enote;
16697 Elf_Internal_Note inote;
16699 uint64_t offset = shdr->sh_offset;
16700 uint64_t align = shdr->sh_addralign;
16701 uint64_t length = shdr->sh_size;
16703 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
16704 if (enote == NULL)
16705 continue;
16707 if (align < 4)
16708 align = 4;
16709 else if (align != 4 && align != 8)
16711 free (enote);
16712 continue;
16715 end = (char *) enote + length;
16716 data_remaining = end - (char *) enote;
16718 if (!is_ia64_vms (filedata))
16720 min_notesz = offsetof (Elf_External_Note, name);
16721 if (data_remaining < min_notesz)
16723 warn (_("\
16724 malformed note encountered in section %s whilst scanning for build-id note\n"),
16725 printable_section_name (filedata, shdr));
16726 free (enote);
16727 continue;
16729 data_remaining -= min_notesz;
16731 inote.type = BYTE_GET (enote->type);
16732 inote.namesz = BYTE_GET (enote->namesz);
16733 inote.namedata = enote->name;
16734 inote.descsz = BYTE_GET (enote->descsz);
16735 inote.descdata = ((char *) enote
16736 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
16737 inote.descpos = offset + (inote.descdata - (char *) enote);
16738 next = ((char *) enote
16739 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
16741 else
16743 Elf64_External_VMS_Note *vms_enote;
16745 /* PR binutils/15191
16746 Make sure that there is enough data to read. */
16747 min_notesz = offsetof (Elf64_External_VMS_Note, name);
16748 if (data_remaining < min_notesz)
16750 warn (_("\
16751 malformed note encountered in section %s whilst scanning for build-id note\n"),
16752 printable_section_name (filedata, shdr));
16753 free (enote);
16754 continue;
16756 data_remaining -= min_notesz;
16758 vms_enote = (Elf64_External_VMS_Note *) enote;
16759 inote.type = BYTE_GET (vms_enote->type);
16760 inote.namesz = BYTE_GET (vms_enote->namesz);
16761 inote.namedata = vms_enote->name;
16762 inote.descsz = BYTE_GET (vms_enote->descsz);
16763 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16764 inote.descpos = offset + (inote.descdata - (char *) enote);
16765 next = inote.descdata + align_power (inote.descsz, 3);
16768 /* Skip malformed notes. */
16769 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
16770 || (size_t) (inote.descdata - inote.namedata) > data_remaining
16771 || (size_t) (next - inote.descdata) < inote.descsz
16772 || ((size_t) (next - inote.descdata)
16773 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
16775 warn (_("\
16776 malformed note encountered in section %s whilst scanning for build-id note\n"),
16777 printable_section_name (filedata, shdr));
16778 free (enote);
16779 continue;
16782 /* Check if this is the build-id note. If so then convert the build-id
16783 bytes to a hex string. */
16784 if (inote.namesz > 0
16785 && startswith (inote.namedata, "GNU")
16786 && inote.type == NT_GNU_BUILD_ID)
16788 size_t j;
16789 char * build_id;
16791 build_id = malloc (inote.descsz * 2 + 1);
16792 if (build_id == NULL)
16794 free (enote);
16795 return NULL;
16798 for (j = 0; j < inote.descsz; ++j)
16799 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
16800 build_id[inote.descsz * 2] = '\0';
16801 free (enote);
16803 return (unsigned char *) build_id;
16805 free (enote);
16808 return NULL;
16810 #endif /* HAVE_LIBDEBUGINFOD */
16812 /* If this is not NULL, load_debug_section will only look for sections
16813 within the list of sections given here. */
16814 static unsigned int * section_subset = NULL;
16816 bool
16817 load_debug_section (enum dwarf_section_display_enum debug, void * data)
16819 struct dwarf_section * section = &debug_displays [debug].section;
16820 Elf_Internal_Shdr * sec;
16821 Filedata * filedata = (Filedata *) data;
16823 if (!dump_any_debugging)
16824 return false;
16826 /* Without section headers we cannot find any sections. */
16827 if (filedata->section_headers == NULL)
16828 return false;
16830 if (filedata->string_table == NULL
16831 && filedata->file_header.e_shstrndx != SHN_UNDEF
16832 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
16834 Elf_Internal_Shdr * strs;
16836 /* Read in the string table, so that we have section names to scan. */
16837 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
16839 if (strs != NULL && strs->sh_size != 0)
16841 filedata->string_table
16842 = (char *) get_data (NULL, filedata, strs->sh_offset,
16843 1, strs->sh_size, _("string table"));
16845 filedata->string_table_length
16846 = filedata->string_table != NULL ? strs->sh_size : 0;
16850 /* Locate the debug section. */
16851 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
16852 if (sec != NULL)
16853 section->name = section->uncompressed_name;
16854 else
16856 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
16857 if (sec != NULL)
16858 section->name = section->compressed_name;
16860 if (sec == NULL)
16861 return false;
16863 /* If we're loading from a subset of sections, and we've loaded
16864 a section matching this name before, it's likely that it's a
16865 different one. */
16866 if (section_subset != NULL)
16867 free_debug_section (debug);
16869 return load_specific_debug_section (debug, sec, data);
16872 void
16873 free_debug_section (enum dwarf_section_display_enum debug)
16875 struct dwarf_section * section = &debug_displays [debug].section;
16877 if (section->start == NULL)
16878 return;
16880 free ((char *) section->start);
16881 section->start = NULL;
16882 section->address = 0;
16883 section->size = 0;
16885 free (section->reloc_info);
16886 section->reloc_info = NULL;
16887 section->num_relocs = 0;
16890 static bool
16891 display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
16893 const char *name = (section_name_valid (filedata, section)
16894 ? section_name (filedata, section) : "");
16895 const char *print_name = printable_section_name (filedata, section);
16896 uint64_t length;
16897 bool result = true;
16898 int i;
16900 length = section->sh_size;
16901 if (length == 0)
16903 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
16904 return true;
16906 if (section->sh_type == SHT_NOBITS)
16908 /* There is no point in dumping the contents of a debugging section
16909 which has the NOBITS type - the bits in the file will be random.
16910 This can happen when a file containing a .eh_frame section is
16911 stripped with the --only-keep-debug command line option. */
16912 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16913 print_name);
16914 return false;
16917 if (startswith (name, ".gnu.linkonce.wi."))
16918 name = ".debug_info";
16920 /* See if we know how to display the contents of this section. */
16921 for (i = 0; i < max; i++)
16923 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16924 struct dwarf_section_display * display = debug_displays + i;
16925 struct dwarf_section * sec = & display->section;
16927 if (streq (sec->uncompressed_name, name)
16928 || (id == line && startswith (name, ".debug_line."))
16929 || streq (sec->compressed_name, name))
16931 bool secondary = (section != find_section (filedata, name));
16933 if (secondary)
16934 free_debug_section (id);
16936 if (i == line && startswith (name, ".debug_line."))
16937 sec->name = name;
16938 else if (streq (sec->uncompressed_name, name))
16939 sec->name = sec->uncompressed_name;
16940 else
16941 sec->name = sec->compressed_name;
16943 if (load_specific_debug_section (id, section, filedata))
16945 /* If this debug section is part of a CU/TU set in a .dwp file,
16946 restrict load_debug_section to the sections in that set. */
16947 section_subset = find_cu_tu_set (filedata, shndx);
16949 result &= display->display (sec, filedata);
16951 section_subset = NULL;
16953 if (secondary || (id != info && id != abbrev && id != debug_addr))
16954 free_debug_section (id);
16956 break;
16960 if (i == max)
16962 printf (_("Unrecognized debug section: %s\n"), print_name);
16963 result = false;
16966 return result;
16969 /* Set DUMP_SECTS for all sections where dumps were requested
16970 based on section name. */
16972 static void
16973 initialise_dumps_byname (Filedata * filedata)
16975 struct dump_list_entry * cur;
16977 for (cur = dump_sects_byname; cur; cur = cur->next)
16979 unsigned int i;
16980 bool any = false;
16982 for (i = 0; i < filedata->file_header.e_shnum; i++)
16983 if (section_name_valid (filedata, filedata->section_headers + i)
16984 && streq (section_name (filedata, filedata->section_headers + i),
16985 cur->name))
16987 request_dump_bynumber (&filedata->dump, i, cur->type);
16988 any = true;
16991 if (!any && !filedata->is_separate)
16992 warn (_("Section '%s' was not dumped because it does not exist\n"),
16993 cur->name);
16997 static bool
16998 process_section_contents (Filedata * filedata)
17000 Elf_Internal_Shdr * section;
17001 unsigned int i;
17002 bool res = true;
17004 if (! do_dump)
17005 return true;
17007 initialise_dumps_byname (filedata);
17009 for (i = 0, section = filedata->section_headers;
17010 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
17011 i++, section++)
17013 dump_type dump = filedata->dump.dump_sects[i];
17015 if (filedata->is_separate && ! process_links)
17016 dump &= DEBUG_DUMP;
17018 #ifdef SUPPORT_DISASSEMBLY
17019 if (dump & DISASS_DUMP)
17021 if (! disassemble_section (section, filedata))
17022 res = false;
17024 #endif
17025 if (dump & HEX_DUMP)
17027 if (! dump_section_as_bytes (section, filedata, false))
17028 res = false;
17031 if (dump & RELOC_DUMP)
17033 if (! dump_section_as_bytes (section, filedata, true))
17034 res = false;
17037 if (dump & STRING_DUMP)
17039 if (! dump_section_as_strings (section, filedata))
17040 res = false;
17043 if (dump & DEBUG_DUMP)
17045 if (! display_debug_section (i, section, filedata))
17046 res = false;
17049 #ifdef ENABLE_LIBCTF
17050 if (dump & CTF_DUMP)
17052 if (! dump_section_as_ctf (section, filedata))
17053 res = false;
17055 #endif
17056 if (dump & SFRAME_DUMP)
17058 if (! dump_section_as_sframe (section, filedata))
17059 res = false;
17063 if (! filedata->is_separate)
17065 /* Check to see if the user requested a
17066 dump of a section that does not exist. */
17067 for (; i < filedata->dump.num_dump_sects; i++)
17068 if (filedata->dump.dump_sects[i])
17070 warn (_("Section %d was not dumped because it does not exist!\n"), i);
17071 res = false;
17075 return res;
17078 static void
17079 process_mips_fpe_exception (int mask)
17081 if (mask)
17083 bool first = true;
17085 if (mask & OEX_FPU_INEX)
17086 fputs ("INEX", stdout), first = false;
17087 if (mask & OEX_FPU_UFLO)
17088 printf ("%sUFLO", first ? "" : "|"), first = false;
17089 if (mask & OEX_FPU_OFLO)
17090 printf ("%sOFLO", first ? "" : "|"), first = false;
17091 if (mask & OEX_FPU_DIV0)
17092 printf ("%sDIV0", first ? "" : "|"), first = false;
17093 if (mask & OEX_FPU_INVAL)
17094 printf ("%sINVAL", first ? "" : "|");
17096 else
17097 fputs ("0", stdout);
17100 /* Display's the value of TAG at location P. If TAG is
17101 greater than 0 it is assumed to be an unknown tag, and
17102 a message is printed to this effect. Otherwise it is
17103 assumed that a message has already been printed.
17105 If the bottom bit of TAG is set it assumed to have a
17106 string value, otherwise it is assumed to have an integer
17107 value.
17109 Returns an updated P pointing to the first unread byte
17110 beyond the end of TAG's value.
17112 Reads at or beyond END will not be made. */
17114 static unsigned char *
17115 display_tag_value (signed int tag,
17116 unsigned char * p,
17117 const unsigned char * const end)
17119 uint64_t val;
17121 if (tag > 0)
17122 printf (" Tag_unknown_%d: ", tag);
17124 if (p >= end)
17126 warn (_("<corrupt tag>\n"));
17128 else if (tag & 1)
17130 /* PR 17531 file: 027-19978-0.004. */
17131 size_t maxlen = (end - p) - 1;
17133 putchar ('"');
17134 if (maxlen > 0)
17136 print_symbol_name ((int) maxlen, (const char *) p);
17137 p += strnlen ((char *) p, maxlen) + 1;
17139 else
17141 printf (_("<corrupt string tag>"));
17142 p = (unsigned char *) end;
17144 printf ("\"\n");
17146 else
17148 READ_ULEB (val, p, end);
17149 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
17152 assert (p <= end);
17153 return p;
17156 /* ARC ABI attributes section. */
17158 static unsigned char *
17159 display_arc_attribute (unsigned char * p,
17160 const unsigned char * const end)
17162 unsigned int tag;
17163 unsigned int val;
17165 READ_ULEB (tag, p, end);
17167 switch (tag)
17169 case Tag_ARC_PCS_config:
17170 READ_ULEB (val, p, end);
17171 printf (" Tag_ARC_PCS_config: ");
17172 switch (val)
17174 case 0:
17175 printf (_("Absent/Non standard\n"));
17176 break;
17177 case 1:
17178 printf (_("Bare metal/mwdt\n"));
17179 break;
17180 case 2:
17181 printf (_("Bare metal/newlib\n"));
17182 break;
17183 case 3:
17184 printf (_("Linux/uclibc\n"));
17185 break;
17186 case 4:
17187 printf (_("Linux/glibc\n"));
17188 break;
17189 default:
17190 printf (_("Unknown\n"));
17191 break;
17193 break;
17195 case Tag_ARC_CPU_base:
17196 READ_ULEB (val, p, end);
17197 printf (" Tag_ARC_CPU_base: ");
17198 switch (val)
17200 default:
17201 case TAG_CPU_NONE:
17202 printf (_("Absent\n"));
17203 break;
17204 case TAG_CPU_ARC6xx:
17205 printf ("ARC6xx\n");
17206 break;
17207 case TAG_CPU_ARC7xx:
17208 printf ("ARC7xx\n");
17209 break;
17210 case TAG_CPU_ARCEM:
17211 printf ("ARCEM\n");
17212 break;
17213 case TAG_CPU_ARCHS:
17214 printf ("ARCHS\n");
17215 break;
17217 break;
17219 case Tag_ARC_CPU_variation:
17220 READ_ULEB (val, p, end);
17221 printf (" Tag_ARC_CPU_variation: ");
17222 switch (val)
17224 default:
17225 if (val > 0 && val < 16)
17226 printf ("Core%d\n", val);
17227 else
17228 printf ("Unknown\n");
17229 break;
17231 case 0:
17232 printf (_("Absent\n"));
17233 break;
17235 break;
17237 case Tag_ARC_CPU_name:
17238 printf (" Tag_ARC_CPU_name: ");
17239 p = display_tag_value (-1, p, end);
17240 break;
17242 case Tag_ARC_ABI_rf16:
17243 READ_ULEB (val, p, end);
17244 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
17245 break;
17247 case Tag_ARC_ABI_osver:
17248 READ_ULEB (val, p, end);
17249 printf (" Tag_ARC_ABI_osver: v%d\n", val);
17250 break;
17252 case Tag_ARC_ABI_pic:
17253 case Tag_ARC_ABI_sda:
17254 READ_ULEB (val, p, end);
17255 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
17256 : " Tag_ARC_ABI_pic: ");
17257 switch (val)
17259 case 0:
17260 printf (_("Absent\n"));
17261 break;
17262 case 1:
17263 printf ("MWDT\n");
17264 break;
17265 case 2:
17266 printf ("GNU\n");
17267 break;
17268 default:
17269 printf (_("Unknown\n"));
17270 break;
17272 break;
17274 case Tag_ARC_ABI_tls:
17275 READ_ULEB (val, p, end);
17276 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
17277 break;
17279 case Tag_ARC_ABI_enumsize:
17280 READ_ULEB (val, p, end);
17281 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
17282 _("smallest"));
17283 break;
17285 case Tag_ARC_ABI_exceptions:
17286 READ_ULEB (val, p, end);
17287 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
17288 : _("default"));
17289 break;
17291 case Tag_ARC_ABI_double_size:
17292 READ_ULEB (val, p, end);
17293 printf (" Tag_ARC_ABI_double_size: %d\n", val);
17294 break;
17296 case Tag_ARC_ISA_config:
17297 printf (" Tag_ARC_ISA_config: ");
17298 p = display_tag_value (-1, p, end);
17299 break;
17301 case Tag_ARC_ISA_apex:
17302 printf (" Tag_ARC_ISA_apex: ");
17303 p = display_tag_value (-1, p, end);
17304 break;
17306 case Tag_ARC_ISA_mpy_option:
17307 READ_ULEB (val, p, end);
17308 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
17309 break;
17311 case Tag_ARC_ATR_version:
17312 READ_ULEB (val, p, end);
17313 printf (" Tag_ARC_ATR_version: %d\n", val);
17314 break;
17316 default:
17317 return display_tag_value (tag & 1, p, end);
17320 return p;
17323 /* ARM EABI attributes section. */
17324 typedef struct
17326 unsigned int tag;
17327 const char * name;
17328 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
17329 unsigned int type;
17330 const char *const *table;
17331 } arm_attr_public_tag;
17333 static const char *const arm_attr_tag_CPU_arch[] =
17334 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
17335 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
17336 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
17337 "v8.1-M.mainline", "v9"};
17338 static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
17339 static const char *const arm_attr_tag_THUMB_ISA_use[] =
17340 {"No", "Thumb-1", "Thumb-2", "Yes"};
17341 static const char *const arm_attr_tag_FP_arch[] =
17342 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
17343 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
17344 static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
17345 static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
17346 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
17347 "NEON for ARMv8.1"};
17348 static const char *const arm_attr_tag_PCS_config[] =
17349 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
17350 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
17351 static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
17352 {"V6", "SB", "TLS", "Unused"};
17353 static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
17354 {"Absolute", "PC-relative", "SB-relative", "None"};
17355 static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
17356 {"Absolute", "PC-relative", "None"};
17357 static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
17358 {"None", "direct", "GOT-indirect"};
17359 static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
17360 {"None", "??? 1", "2", "??? 3", "4"};
17361 static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
17362 static const char *const arm_attr_tag_ABI_FP_denormal[] =
17363 {"Unused", "Needed", "Sign only"};
17364 static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
17365 static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
17366 static const char *const arm_attr_tag_ABI_FP_number_model[] =
17367 {"Unused", "Finite", "RTABI", "IEEE 754"};
17368 static const char *const arm_attr_tag_ABI_enum_size[] =
17369 {"Unused", "small", "int", "forced to int"};
17370 static const char *const arm_attr_tag_ABI_HardFP_use[] =
17371 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
17372 static const char *const arm_attr_tag_ABI_VFP_args[] =
17373 {"AAPCS", "VFP registers", "custom", "compatible"};
17374 static const char *const arm_attr_tag_ABI_WMMX_args[] =
17375 {"AAPCS", "WMMX registers", "custom"};
17376 static const char *const arm_attr_tag_ABI_optimization_goals[] =
17377 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
17378 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
17379 static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
17380 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
17381 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
17382 static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
17383 static const char *const arm_attr_tag_FP_HP_extension[] =
17384 {"Not Allowed", "Allowed"};
17385 static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
17386 {"None", "IEEE 754", "Alternative Format"};
17387 static const char *const arm_attr_tag_DSP_extension[] =
17388 {"Follow architecture", "Allowed"};
17389 static const char *const arm_attr_tag_MPextension_use[] =
17390 {"Not Allowed", "Allowed"};
17391 static const char *const arm_attr_tag_DIV_use[] =
17392 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
17393 "Allowed in v7-A with integer division extension"};
17394 static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
17395 static const char *const arm_attr_tag_Virtualization_use[] =
17396 {"Not Allowed", "TrustZone", "Virtualization Extensions",
17397 "TrustZone and Virtualization Extensions"};
17398 static const char *const arm_attr_tag_MPextension_use_legacy[] =
17399 {"Not Allowed", "Allowed"};
17401 static const char *const arm_attr_tag_MVE_arch[] =
17402 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
17404 static const char * arm_attr_tag_PAC_extension[] =
17405 {"No PAC/AUT instructions",
17406 "PAC/AUT instructions permitted in the NOP space",
17407 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
17409 static const char * arm_attr_tag_BTI_extension[] =
17410 {"BTI instructions not permitted",
17411 "BTI instructions permitted in the NOP space",
17412 "BTI instructions permitted in the NOP and in the non-NOP space"};
17414 static const char * arm_attr_tag_BTI_use[] =
17415 {"Compiled without branch target enforcement",
17416 "Compiled with branch target enforcement"};
17418 static const char * arm_attr_tag_PACRET_use[] =
17419 {"Compiled without return address signing and authentication",
17420 "Compiled with return address signing and authentication"};
17422 #define LOOKUP(id, name) \
17423 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
17424 static arm_attr_public_tag arm_attr_public_tags[] =
17426 {4, "CPU_raw_name", 1, NULL},
17427 {5, "CPU_name", 1, NULL},
17428 LOOKUP(6, CPU_arch),
17429 {7, "CPU_arch_profile", 0, NULL},
17430 LOOKUP(8, ARM_ISA_use),
17431 LOOKUP(9, THUMB_ISA_use),
17432 LOOKUP(10, FP_arch),
17433 LOOKUP(11, WMMX_arch),
17434 LOOKUP(12, Advanced_SIMD_arch),
17435 LOOKUP(13, PCS_config),
17436 LOOKUP(14, ABI_PCS_R9_use),
17437 LOOKUP(15, ABI_PCS_RW_data),
17438 LOOKUP(16, ABI_PCS_RO_data),
17439 LOOKUP(17, ABI_PCS_GOT_use),
17440 LOOKUP(18, ABI_PCS_wchar_t),
17441 LOOKUP(19, ABI_FP_rounding),
17442 LOOKUP(20, ABI_FP_denormal),
17443 LOOKUP(21, ABI_FP_exceptions),
17444 LOOKUP(22, ABI_FP_user_exceptions),
17445 LOOKUP(23, ABI_FP_number_model),
17446 {24, "ABI_align_needed", 0, NULL},
17447 {25, "ABI_align_preserved", 0, NULL},
17448 LOOKUP(26, ABI_enum_size),
17449 LOOKUP(27, ABI_HardFP_use),
17450 LOOKUP(28, ABI_VFP_args),
17451 LOOKUP(29, ABI_WMMX_args),
17452 LOOKUP(30, ABI_optimization_goals),
17453 LOOKUP(31, ABI_FP_optimization_goals),
17454 {32, "compatibility", 0, NULL},
17455 LOOKUP(34, CPU_unaligned_access),
17456 LOOKUP(36, FP_HP_extension),
17457 LOOKUP(38, ABI_FP_16bit_format),
17458 LOOKUP(42, MPextension_use),
17459 LOOKUP(44, DIV_use),
17460 LOOKUP(46, DSP_extension),
17461 LOOKUP(48, MVE_arch),
17462 LOOKUP(50, PAC_extension),
17463 LOOKUP(52, BTI_extension),
17464 LOOKUP(74, BTI_use),
17465 LOOKUP(76, PACRET_use),
17466 {64, "nodefaults", 0, NULL},
17467 {65, "also_compatible_with", 0, NULL},
17468 LOOKUP(66, T2EE_use),
17469 {67, "conformance", 1, NULL},
17470 LOOKUP(68, Virtualization_use),
17471 LOOKUP(70, MPextension_use_legacy)
17473 #undef LOOKUP
17475 static unsigned char *
17476 display_arm_attribute (unsigned char * p,
17477 const unsigned char * const end)
17479 unsigned int tag;
17480 unsigned int val;
17481 arm_attr_public_tag * attr;
17482 unsigned i;
17483 unsigned int type;
17485 READ_ULEB (tag, p, end);
17486 attr = NULL;
17487 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
17489 if (arm_attr_public_tags[i].tag == tag)
17491 attr = &arm_attr_public_tags[i];
17492 break;
17496 if (attr)
17498 printf (" Tag_%s: ", attr->name);
17499 switch (attr->type)
17501 case 0:
17502 switch (tag)
17504 case 7: /* Tag_CPU_arch_profile. */
17505 READ_ULEB (val, p, end);
17506 switch (val)
17508 case 0: printf (_("None\n")); break;
17509 case 'A': printf (_("Application\n")); break;
17510 case 'R': printf (_("Realtime\n")); break;
17511 case 'M': printf (_("Microcontroller\n")); break;
17512 case 'S': printf (_("Application or Realtime\n")); break;
17513 default: printf ("??? (%d)\n", val); break;
17515 break;
17517 case 24: /* Tag_align_needed. */
17518 READ_ULEB (val, p, end);
17519 switch (val)
17521 case 0: printf (_("None\n")); break;
17522 case 1: printf (_("8-byte\n")); break;
17523 case 2: printf (_("4-byte\n")); break;
17524 case 3: printf ("??? 3\n"); break;
17525 default:
17526 if (val <= 12)
17527 printf (_("8-byte and up to %d-byte extended\n"),
17528 1 << val);
17529 else
17530 printf ("??? (%d)\n", val);
17531 break;
17533 break;
17535 case 25: /* Tag_align_preserved. */
17536 READ_ULEB (val, p, end);
17537 switch (val)
17539 case 0: printf (_("None\n")); break;
17540 case 1: printf (_("8-byte, except leaf SP\n")); break;
17541 case 2: printf (_("8-byte\n")); break;
17542 case 3: printf ("??? 3\n"); break;
17543 default:
17544 if (val <= 12)
17545 printf (_("8-byte and up to %d-byte extended\n"),
17546 1 << val);
17547 else
17548 printf ("??? (%d)\n", val);
17549 break;
17551 break;
17553 case 32: /* Tag_compatibility. */
17555 READ_ULEB (val, p, end);
17556 printf (_("flag = %d, vendor = "), val);
17557 if (p < end - 1)
17559 size_t maxlen = (end - p) - 1;
17561 print_symbol_name ((int) maxlen, (const char *) p);
17562 p += strnlen ((char *) p, maxlen) + 1;
17564 else
17566 printf (_("<corrupt>"));
17567 p = (unsigned char *) end;
17569 putchar ('\n');
17571 break;
17573 case 64: /* Tag_nodefaults. */
17574 /* PR 17531: file: 001-505008-0.01. */
17575 if (p < end)
17576 p++;
17577 printf (_("True\n"));
17578 break;
17580 case 65: /* Tag_also_compatible_with. */
17581 READ_ULEB (val, p, end);
17582 if (val == 6 /* Tag_CPU_arch. */)
17584 READ_ULEB (val, p, end);
17585 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
17586 printf ("??? (%d)\n", val);
17587 else
17588 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
17590 else
17591 printf ("???\n");
17592 while (p < end && *(p++) != '\0' /* NUL terminator. */)
17594 break;
17596 default:
17597 printf (_("<unknown: %d>\n"), tag);
17598 break;
17600 return p;
17602 case 1:
17603 return display_tag_value (-1, p, end);
17604 case 2:
17605 return display_tag_value (0, p, end);
17607 default:
17608 assert (attr->type & 0x80);
17609 READ_ULEB (val, p, end);
17610 type = attr->type & 0x7f;
17611 if (val >= type)
17612 printf ("??? (%d)\n", val);
17613 else
17614 printf ("%s\n", attr->table[val]);
17615 return p;
17619 return display_tag_value (tag, p, end);
17622 static unsigned char *
17623 display_gnu_attribute (unsigned char * p,
17624 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
17625 const unsigned char * const end)
17627 unsigned int tag;
17628 unsigned int val;
17630 READ_ULEB (tag, p, end);
17632 /* Tag_compatibility is the only generic GNU attribute defined at
17633 present. */
17634 if (tag == 32)
17636 READ_ULEB (val, p, end);
17638 printf (_("flag = %d, vendor = "), val);
17639 if (p == end)
17641 printf (_("<corrupt>\n"));
17642 warn (_("corrupt vendor attribute\n"));
17644 else
17646 if (p < end - 1)
17648 size_t maxlen = (end - p) - 1;
17650 print_symbol_name ((int) maxlen, (const char *) p);
17651 p += strnlen ((char *) p, maxlen) + 1;
17653 else
17655 printf (_("<corrupt>"));
17656 p = (unsigned char *) end;
17658 putchar ('\n');
17660 return p;
17663 if ((tag & 2) == 0 && display_proc_gnu_attribute)
17664 return display_proc_gnu_attribute (p, tag, end);
17666 return display_tag_value (tag, p, end);
17669 static unsigned char *
17670 display_m68k_gnu_attribute (unsigned char * p,
17671 unsigned int tag,
17672 const unsigned char * const end)
17674 unsigned int val;
17676 if (tag == Tag_GNU_M68K_ABI_FP)
17678 printf (" Tag_GNU_M68K_ABI_FP: ");
17679 if (p == end)
17681 printf (_("<corrupt>\n"));
17682 return p;
17684 READ_ULEB (val, p, end);
17686 if (val > 3)
17687 printf ("(%#x), ", val);
17689 switch (val & 3)
17691 case 0:
17692 printf (_("unspecified hard/soft float\n"));
17693 break;
17694 case 1:
17695 printf (_("hard float\n"));
17696 break;
17697 case 2:
17698 printf (_("soft float\n"));
17699 break;
17701 return p;
17704 return display_tag_value (tag & 1, p, end);
17707 static unsigned char *
17708 display_power_gnu_attribute (unsigned char * p,
17709 unsigned int tag,
17710 const unsigned char * const end)
17712 unsigned int val;
17714 if (tag == Tag_GNU_Power_ABI_FP)
17716 printf (" Tag_GNU_Power_ABI_FP: ");
17717 if (p == end)
17719 printf (_("<corrupt>\n"));
17720 return p;
17722 READ_ULEB (val, p, end);
17724 if (val > 15)
17725 printf ("(%#x), ", val);
17727 switch (val & 3)
17729 case 0:
17730 printf (_("unspecified hard/soft float, "));
17731 break;
17732 case 1:
17733 printf (_("hard float, "));
17734 break;
17735 case 2:
17736 printf (_("soft float, "));
17737 break;
17738 case 3:
17739 printf (_("single-precision hard float, "));
17740 break;
17743 switch (val & 0xC)
17745 case 0:
17746 printf (_("unspecified long double\n"));
17747 break;
17748 case 4:
17749 printf (_("128-bit IBM long double\n"));
17750 break;
17751 case 8:
17752 printf (_("64-bit long double\n"));
17753 break;
17754 case 12:
17755 printf (_("128-bit IEEE long double\n"));
17756 break;
17758 return p;
17761 if (tag == Tag_GNU_Power_ABI_Vector)
17763 printf (" Tag_GNU_Power_ABI_Vector: ");
17764 if (p == end)
17766 printf (_("<corrupt>\n"));
17767 return p;
17769 READ_ULEB (val, p, end);
17771 if (val > 3)
17772 printf ("(%#x), ", val);
17774 switch (val & 3)
17776 case 0:
17777 printf (_("unspecified\n"));
17778 break;
17779 case 1:
17780 printf (_("generic\n"));
17781 break;
17782 case 2:
17783 printf ("AltiVec\n");
17784 break;
17785 case 3:
17786 printf ("SPE\n");
17787 break;
17789 return p;
17792 if (tag == Tag_GNU_Power_ABI_Struct_Return)
17794 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
17795 if (p == end)
17797 printf (_("<corrupt>\n"));
17798 return p;
17800 READ_ULEB (val, p, end);
17802 if (val > 2)
17803 printf ("(%#x), ", val);
17805 switch (val & 3)
17807 case 0:
17808 printf (_("unspecified\n"));
17809 break;
17810 case 1:
17811 printf ("r3/r4\n");
17812 break;
17813 case 2:
17814 printf (_("memory\n"));
17815 break;
17816 case 3:
17817 printf ("???\n");
17818 break;
17820 return p;
17823 return display_tag_value (tag & 1, p, end);
17826 static unsigned char *
17827 display_s390_gnu_attribute (unsigned char * p,
17828 unsigned int tag,
17829 const unsigned char * const end)
17831 unsigned int val;
17833 if (tag == Tag_GNU_S390_ABI_Vector)
17835 printf (" Tag_GNU_S390_ABI_Vector: ");
17836 READ_ULEB (val, p, end);
17838 switch (val)
17840 case 0:
17841 printf (_("any\n"));
17842 break;
17843 case 1:
17844 printf (_("software\n"));
17845 break;
17846 case 2:
17847 printf (_("hardware\n"));
17848 break;
17849 default:
17850 printf ("??? (%d)\n", val);
17851 break;
17853 return p;
17856 return display_tag_value (tag & 1, p, end);
17859 static void
17860 display_sparc_hwcaps (unsigned int mask)
17862 if (mask)
17864 bool first = true;
17866 if (mask & ELF_SPARC_HWCAP_MUL32)
17867 fputs ("mul32", stdout), first = false;
17868 if (mask & ELF_SPARC_HWCAP_DIV32)
17869 printf ("%sdiv32", first ? "" : "|"), first = false;
17870 if (mask & ELF_SPARC_HWCAP_FSMULD)
17871 printf ("%sfsmuld", first ? "" : "|"), first = false;
17872 if (mask & ELF_SPARC_HWCAP_V8PLUS)
17873 printf ("%sv8plus", first ? "" : "|"), first = false;
17874 if (mask & ELF_SPARC_HWCAP_POPC)
17875 printf ("%spopc", first ? "" : "|"), first = false;
17876 if (mask & ELF_SPARC_HWCAP_VIS)
17877 printf ("%svis", first ? "" : "|"), first = false;
17878 if (mask & ELF_SPARC_HWCAP_VIS2)
17879 printf ("%svis2", first ? "" : "|"), first = false;
17880 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
17881 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
17882 if (mask & ELF_SPARC_HWCAP_FMAF)
17883 printf ("%sfmaf", first ? "" : "|"), first = false;
17884 if (mask & ELF_SPARC_HWCAP_VIS3)
17885 printf ("%svis3", first ? "" : "|"), first = false;
17886 if (mask & ELF_SPARC_HWCAP_HPC)
17887 printf ("%shpc", first ? "" : "|"), first = false;
17888 if (mask & ELF_SPARC_HWCAP_RANDOM)
17889 printf ("%srandom", first ? "" : "|"), first = false;
17890 if (mask & ELF_SPARC_HWCAP_TRANS)
17891 printf ("%strans", first ? "" : "|"), first = false;
17892 if (mask & ELF_SPARC_HWCAP_FJFMAU)
17893 printf ("%sfjfmau", first ? "" : "|"), first = false;
17894 if (mask & ELF_SPARC_HWCAP_IMA)
17895 printf ("%sima", first ? "" : "|"), first = false;
17896 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
17897 printf ("%scspare", first ? "" : "|"), first = false;
17899 else
17900 fputc ('0', stdout);
17901 fputc ('\n', stdout);
17904 static void
17905 display_sparc_hwcaps2 (unsigned int mask)
17907 if (mask)
17909 bool first = true;
17911 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
17912 fputs ("fjathplus", stdout), first = false;
17913 if (mask & ELF_SPARC_HWCAP2_VIS3B)
17914 printf ("%svis3b", first ? "" : "|"), first = false;
17915 if (mask & ELF_SPARC_HWCAP2_ADP)
17916 printf ("%sadp", first ? "" : "|"), first = false;
17917 if (mask & ELF_SPARC_HWCAP2_SPARC5)
17918 printf ("%ssparc5", first ? "" : "|"), first = false;
17919 if (mask & ELF_SPARC_HWCAP2_MWAIT)
17920 printf ("%smwait", first ? "" : "|"), first = false;
17921 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
17922 printf ("%sxmpmul", first ? "" : "|"), first = false;
17923 if (mask & ELF_SPARC_HWCAP2_XMONT)
17924 printf ("%sxmont2", first ? "" : "|"), first = false;
17925 if (mask & ELF_SPARC_HWCAP2_NSEC)
17926 printf ("%snsec", first ? "" : "|"), first = false;
17927 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
17928 printf ("%sfjathhpc", first ? "" : "|"), first = false;
17929 if (mask & ELF_SPARC_HWCAP2_FJDES)
17930 printf ("%sfjdes", first ? "" : "|"), first = false;
17931 if (mask & ELF_SPARC_HWCAP2_FJAES)
17932 printf ("%sfjaes", first ? "" : "|"), first = false;
17934 else
17935 fputc ('0', stdout);
17936 fputc ('\n', stdout);
17939 static unsigned char *
17940 display_sparc_gnu_attribute (unsigned char * p,
17941 unsigned int tag,
17942 const unsigned char * const end)
17944 unsigned int val;
17946 if (tag == Tag_GNU_Sparc_HWCAPS)
17948 READ_ULEB (val, p, end);
17949 printf (" Tag_GNU_Sparc_HWCAPS: ");
17950 display_sparc_hwcaps (val);
17951 return p;
17953 if (tag == Tag_GNU_Sparc_HWCAPS2)
17955 READ_ULEB (val, p, end);
17956 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17957 display_sparc_hwcaps2 (val);
17958 return p;
17961 return display_tag_value (tag, p, end);
17964 static void
17965 print_mips_fp_abi_value (unsigned int val)
17967 switch (val)
17969 case Val_GNU_MIPS_ABI_FP_ANY:
17970 printf (_("Hard or soft float\n"));
17971 break;
17972 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17973 printf (_("Hard float (double precision)\n"));
17974 break;
17975 case Val_GNU_MIPS_ABI_FP_SINGLE:
17976 printf (_("Hard float (single precision)\n"));
17977 break;
17978 case Val_GNU_MIPS_ABI_FP_SOFT:
17979 printf (_("Soft float\n"));
17980 break;
17981 case Val_GNU_MIPS_ABI_FP_OLD_64:
17982 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17983 break;
17984 case Val_GNU_MIPS_ABI_FP_XX:
17985 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17986 break;
17987 case Val_GNU_MIPS_ABI_FP_64:
17988 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17989 break;
17990 case Val_GNU_MIPS_ABI_FP_64A:
17991 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17992 break;
17993 case Val_GNU_MIPS_ABI_FP_NAN2008:
17994 printf (_("NaN 2008 compatibility\n"));
17995 break;
17996 default:
17997 printf ("??? (%d)\n", val);
17998 break;
18002 static unsigned char *
18003 display_mips_gnu_attribute (unsigned char * p,
18004 unsigned int tag,
18005 const unsigned char * const end)
18007 if (tag == Tag_GNU_MIPS_ABI_FP)
18009 unsigned int val;
18011 printf (" Tag_GNU_MIPS_ABI_FP: ");
18012 READ_ULEB (val, p, end);
18013 print_mips_fp_abi_value (val);
18014 return p;
18017 if (tag == Tag_GNU_MIPS_ABI_MSA)
18019 unsigned int val;
18021 printf (" Tag_GNU_MIPS_ABI_MSA: ");
18022 READ_ULEB (val, p, end);
18024 switch (val)
18026 case Val_GNU_MIPS_ABI_MSA_ANY:
18027 printf (_("Any MSA or not\n"));
18028 break;
18029 case Val_GNU_MIPS_ABI_MSA_128:
18030 printf (_("128-bit MSA\n"));
18031 break;
18032 default:
18033 printf ("??? (%d)\n", val);
18034 break;
18036 return p;
18039 return display_tag_value (tag & 1, p, end);
18042 static unsigned char *
18043 display_tic6x_attribute (unsigned char * p,
18044 const unsigned char * const end)
18046 unsigned int tag;
18047 unsigned int val;
18049 READ_ULEB (tag, p, end);
18051 switch (tag)
18053 case Tag_ISA:
18054 printf (" Tag_ISA: ");
18055 READ_ULEB (val, p, end);
18057 switch (val)
18059 case C6XABI_Tag_ISA_none:
18060 printf (_("None\n"));
18061 break;
18062 case C6XABI_Tag_ISA_C62X:
18063 printf ("C62x\n");
18064 break;
18065 case C6XABI_Tag_ISA_C67X:
18066 printf ("C67x\n");
18067 break;
18068 case C6XABI_Tag_ISA_C67XP:
18069 printf ("C67x+\n");
18070 break;
18071 case C6XABI_Tag_ISA_C64X:
18072 printf ("C64x\n");
18073 break;
18074 case C6XABI_Tag_ISA_C64XP:
18075 printf ("C64x+\n");
18076 break;
18077 case C6XABI_Tag_ISA_C674X:
18078 printf ("C674x\n");
18079 break;
18080 default:
18081 printf ("??? (%d)\n", val);
18082 break;
18084 return p;
18086 case Tag_ABI_wchar_t:
18087 printf (" Tag_ABI_wchar_t: ");
18088 READ_ULEB (val, p, end);
18089 switch (val)
18091 case 0:
18092 printf (_("Not used\n"));
18093 break;
18094 case 1:
18095 printf (_("2 bytes\n"));
18096 break;
18097 case 2:
18098 printf (_("4 bytes\n"));
18099 break;
18100 default:
18101 printf ("??? (%d)\n", val);
18102 break;
18104 return p;
18106 case Tag_ABI_stack_align_needed:
18107 printf (" Tag_ABI_stack_align_needed: ");
18108 READ_ULEB (val, p, end);
18109 switch (val)
18111 case 0:
18112 printf (_("8-byte\n"));
18113 break;
18114 case 1:
18115 printf (_("16-byte\n"));
18116 break;
18117 default:
18118 printf ("??? (%d)\n", val);
18119 break;
18121 return p;
18123 case Tag_ABI_stack_align_preserved:
18124 READ_ULEB (val, p, end);
18125 printf (" Tag_ABI_stack_align_preserved: ");
18126 switch (val)
18128 case 0:
18129 printf (_("8-byte\n"));
18130 break;
18131 case 1:
18132 printf (_("16-byte\n"));
18133 break;
18134 default:
18135 printf ("??? (%d)\n", val);
18136 break;
18138 return p;
18140 case Tag_ABI_DSBT:
18141 READ_ULEB (val, p, end);
18142 printf (" Tag_ABI_DSBT: ");
18143 switch (val)
18145 case 0:
18146 printf (_("DSBT addressing not used\n"));
18147 break;
18148 case 1:
18149 printf (_("DSBT addressing used\n"));
18150 break;
18151 default:
18152 printf ("??? (%d)\n", val);
18153 break;
18155 return p;
18157 case Tag_ABI_PID:
18158 READ_ULEB (val, p, end);
18159 printf (" Tag_ABI_PID: ");
18160 switch (val)
18162 case 0:
18163 printf (_("Data addressing position-dependent\n"));
18164 break;
18165 case 1:
18166 printf (_("Data addressing position-independent, GOT near DP\n"));
18167 break;
18168 case 2:
18169 printf (_("Data addressing position-independent, GOT far from DP\n"));
18170 break;
18171 default:
18172 printf ("??? (%d)\n", val);
18173 break;
18175 return p;
18177 case Tag_ABI_PIC:
18178 READ_ULEB (val, p, end);
18179 printf (" Tag_ABI_PIC: ");
18180 switch (val)
18182 case 0:
18183 printf (_("Code addressing position-dependent\n"));
18184 break;
18185 case 1:
18186 printf (_("Code addressing position-independent\n"));
18187 break;
18188 default:
18189 printf ("??? (%d)\n", val);
18190 break;
18192 return p;
18194 case Tag_ABI_array_object_alignment:
18195 READ_ULEB (val, p, end);
18196 printf (" Tag_ABI_array_object_alignment: ");
18197 switch (val)
18199 case 0:
18200 printf (_("8-byte\n"));
18201 break;
18202 case 1:
18203 printf (_("4-byte\n"));
18204 break;
18205 case 2:
18206 printf (_("16-byte\n"));
18207 break;
18208 default:
18209 printf ("??? (%d)\n", val);
18210 break;
18212 return p;
18214 case Tag_ABI_array_object_align_expected:
18215 READ_ULEB (val, p, end);
18216 printf (" Tag_ABI_array_object_align_expected: ");
18217 switch (val)
18219 case 0:
18220 printf (_("8-byte\n"));
18221 break;
18222 case 1:
18223 printf (_("4-byte\n"));
18224 break;
18225 case 2:
18226 printf (_("16-byte\n"));
18227 break;
18228 default:
18229 printf ("??? (%d)\n", val);
18230 break;
18232 return p;
18234 case Tag_ABI_compatibility:
18236 READ_ULEB (val, p, end);
18237 printf (" Tag_ABI_compatibility: ");
18238 printf (_("flag = %d, vendor = "), val);
18239 if (p < end - 1)
18241 size_t maxlen = (end - p) - 1;
18243 print_symbol_name ((int) maxlen, (const char *) p);
18244 p += strnlen ((char *) p, maxlen) + 1;
18246 else
18248 printf (_("<corrupt>"));
18249 p = (unsigned char *) end;
18251 putchar ('\n');
18252 return p;
18255 case Tag_ABI_conformance:
18257 printf (" Tag_ABI_conformance: \"");
18258 if (p < end - 1)
18260 size_t maxlen = (end - p) - 1;
18262 print_symbol_name ((int) maxlen, (const char *) p);
18263 p += strnlen ((char *) p, maxlen) + 1;
18265 else
18267 printf (_("<corrupt>"));
18268 p = (unsigned char *) end;
18270 printf ("\"\n");
18271 return p;
18275 return display_tag_value (tag, p, end);
18278 static void
18279 display_raw_attribute (unsigned char * p, unsigned char const * const end)
18281 uint64_t addr = 0;
18282 size_t bytes = end - p;
18284 assert (end >= p);
18285 while (bytes)
18287 int j;
18288 int k;
18289 int lbytes = (bytes > 16 ? 16 : bytes);
18291 printf (" 0x%8.8" PRIx64 " ", addr);
18293 for (j = 0; j < 16; j++)
18295 if (j < lbytes)
18296 printf ("%2.2x", p[j]);
18297 else
18298 printf (" ");
18300 if ((j & 3) == 3)
18301 printf (" ");
18304 for (j = 0; j < lbytes; j++)
18306 k = p[j];
18307 if (k >= ' ' && k < 0x7f)
18308 printf ("%c", k);
18309 else
18310 printf (".");
18313 putchar ('\n');
18315 p += lbytes;
18316 bytes -= lbytes;
18317 addr += lbytes;
18320 putchar ('\n');
18323 static unsigned char *
18324 display_msp430_attribute (unsigned char * p,
18325 const unsigned char * const end)
18327 uint64_t val;
18328 uint64_t tag;
18330 READ_ULEB (tag, p, end);
18332 switch (tag)
18334 case OFBA_MSPABI_Tag_ISA:
18335 printf (" Tag_ISA: ");
18336 READ_ULEB (val, p, end);
18337 switch (val)
18339 case 0: printf (_("None\n")); break;
18340 case 1: printf (_("MSP430\n")); break;
18341 case 2: printf (_("MSP430X\n")); break;
18342 default: printf ("??? (%" PRId64 ")\n", val); break;
18344 break;
18346 case OFBA_MSPABI_Tag_Code_Model:
18347 printf (" Tag_Code_Model: ");
18348 READ_ULEB (val, p, end);
18349 switch (val)
18351 case 0: printf (_("None\n")); break;
18352 case 1: printf (_("Small\n")); break;
18353 case 2: printf (_("Large\n")); break;
18354 default: printf ("??? (%" PRId64 ")\n", val); break;
18356 break;
18358 case OFBA_MSPABI_Tag_Data_Model:
18359 printf (" Tag_Data_Model: ");
18360 READ_ULEB (val, p, end);
18361 switch (val)
18363 case 0: printf (_("None\n")); break;
18364 case 1: printf (_("Small\n")); break;
18365 case 2: printf (_("Large\n")); break;
18366 case 3: printf (_("Restricted Large\n")); break;
18367 default: printf ("??? (%" PRId64 ")\n", val); break;
18369 break;
18371 default:
18372 printf (_(" <unknown tag %" PRId64 ">: "), tag);
18374 if (tag & 1)
18376 putchar ('"');
18377 if (p < end - 1)
18379 size_t maxlen = (end - p) - 1;
18381 print_symbol_name ((int) maxlen, (const char *) p);
18382 p += strnlen ((char *) p, maxlen) + 1;
18384 else
18386 printf (_("<corrupt>"));
18387 p = (unsigned char *) end;
18389 printf ("\"\n");
18391 else
18393 READ_ULEB (val, p, end);
18394 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
18396 break;
18399 assert (p <= end);
18400 return p;
18403 static unsigned char *
18404 display_msp430_gnu_attribute (unsigned char * p,
18405 unsigned int tag,
18406 const unsigned char * const end)
18408 if (tag == Tag_GNU_MSP430_Data_Region)
18410 uint64_t val;
18412 printf (" Tag_GNU_MSP430_Data_Region: ");
18413 READ_ULEB (val, p, end);
18415 switch (val)
18417 case Val_GNU_MSP430_Data_Region_Any:
18418 printf (_("Any Region\n"));
18419 break;
18420 case Val_GNU_MSP430_Data_Region_Lower:
18421 printf (_("Lower Region Only\n"));
18422 break;
18423 default:
18424 printf ("??? (%" PRIu64 ")\n", val);
18426 return p;
18428 return display_tag_value (tag & 1, p, end);
18431 struct riscv_attr_tag_t {
18432 const char *name;
18433 unsigned int tag;
18436 static struct riscv_attr_tag_t riscv_attr_tag[] =
18438 #define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
18439 T(arch),
18440 T(priv_spec),
18441 T(priv_spec_minor),
18442 T(priv_spec_revision),
18443 T(unaligned_access),
18444 T(stack_align),
18445 #undef T
18448 static unsigned char *
18449 display_riscv_attribute (unsigned char *p,
18450 const unsigned char * const end)
18452 uint64_t val;
18453 uint64_t tag;
18454 struct riscv_attr_tag_t *attr = NULL;
18455 unsigned i;
18457 READ_ULEB (tag, p, end);
18459 /* Find the name of attribute. */
18460 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
18462 if (riscv_attr_tag[i].tag == tag)
18464 attr = &riscv_attr_tag[i];
18465 break;
18469 if (attr)
18470 printf (" %s: ", attr->name);
18471 else
18472 return display_tag_value (tag, p, end);
18474 switch (tag)
18476 case Tag_RISCV_priv_spec:
18477 case Tag_RISCV_priv_spec_minor:
18478 case Tag_RISCV_priv_spec_revision:
18479 READ_ULEB (val, p, end);
18480 printf ("%" PRIu64 "\n", val);
18481 break;
18482 case Tag_RISCV_unaligned_access:
18483 READ_ULEB (val, p, end);
18484 switch (val)
18486 case 0:
18487 printf (_("No unaligned access\n"));
18488 break;
18489 case 1:
18490 printf (_("Unaligned access\n"));
18491 break;
18493 break;
18494 case Tag_RISCV_stack_align:
18495 READ_ULEB (val, p, end);
18496 printf (_("%" PRIu64 "-bytes\n"), val);
18497 break;
18498 case Tag_RISCV_arch:
18499 p = display_tag_value (-1, p, end);
18500 break;
18501 default:
18502 return display_tag_value (tag, p, end);
18505 return p;
18508 static unsigned char *
18509 display_csky_attribute (unsigned char * p,
18510 const unsigned char * const end)
18512 uint64_t tag;
18513 uint64_t val;
18514 READ_ULEB (tag, p, end);
18516 if (tag >= Tag_CSKY_MAX)
18518 return display_tag_value (-1, p, end);
18521 switch (tag)
18523 case Tag_CSKY_ARCH_NAME:
18524 printf (" Tag_CSKY_ARCH_NAME:\t\t");
18525 return display_tag_value (-1, p, end);
18526 case Tag_CSKY_CPU_NAME:
18527 printf (" Tag_CSKY_CPU_NAME:\t\t");
18528 return display_tag_value (-1, p, end);
18530 case Tag_CSKY_ISA_FLAGS:
18531 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
18532 return display_tag_value (0, p, end);
18533 case Tag_CSKY_ISA_EXT_FLAGS:
18534 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
18535 return display_tag_value (0, p, end);
18537 case Tag_CSKY_DSP_VERSION:
18538 printf (" Tag_CSKY_DSP_VERSION:\t\t");
18539 READ_ULEB (val, p, end);
18540 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
18541 printf ("DSP Extension\n");
18542 else if (val == VAL_CSKY_DSP_VERSION_2)
18543 printf ("DSP 2.0\n");
18544 break;
18546 case Tag_CSKY_VDSP_VERSION:
18547 printf (" Tag_CSKY_VDSP_VERSION:\t");
18548 READ_ULEB (val, p, end);
18549 printf ("VDSP Version %" PRId64 "\n", val);
18550 break;
18552 case Tag_CSKY_FPU_VERSION:
18553 printf (" Tag_CSKY_FPU_VERSION:\t\t");
18554 READ_ULEB (val, p, end);
18555 if (val == VAL_CSKY_FPU_VERSION_1)
18556 printf ("ABIV1 FPU Version 1\n");
18557 else if (val == VAL_CSKY_FPU_VERSION_2)
18558 printf ("FPU Version 2\n");
18559 break;
18561 case Tag_CSKY_FPU_ABI:
18562 printf (" Tag_CSKY_FPU_ABI:\t\t");
18563 READ_ULEB (val, p, end);
18564 if (val == VAL_CSKY_FPU_ABI_HARD)
18565 printf ("Hard\n");
18566 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
18567 printf ("SoftFP\n");
18568 else if (val == VAL_CSKY_FPU_ABI_SOFT)
18569 printf ("Soft\n");
18570 break;
18571 case Tag_CSKY_FPU_ROUNDING:
18572 READ_ULEB (val, p, end);
18573 if (val == 1)
18575 printf (" Tag_CSKY_FPU_ROUNDING:\t");
18576 printf ("Needed\n");
18578 break;
18579 case Tag_CSKY_FPU_DENORMAL:
18580 READ_ULEB (val, p, end);
18581 if (val == 1)
18583 printf (" Tag_CSKY_FPU_DENORMAL:\t");
18584 printf ("Needed\n");
18586 break;
18587 case Tag_CSKY_FPU_Exception:
18588 READ_ULEB (val, p, end);
18589 if (val == 1)
18591 printf (" Tag_CSKY_FPU_Exception:\t");
18592 printf ("Needed\n");
18594 break;
18595 case Tag_CSKY_FPU_NUMBER_MODULE:
18596 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
18597 return display_tag_value (-1, p, end);
18598 case Tag_CSKY_FPU_HARDFP:
18599 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
18600 READ_ULEB (val, p, end);
18601 if (val & VAL_CSKY_FPU_HARDFP_HALF)
18602 printf (" Half");
18603 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
18604 printf (" Single");
18605 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
18606 printf (" Double");
18607 printf ("\n");
18608 break;
18609 default:
18610 return display_tag_value (tag, p, end);
18612 return p;
18615 static bool
18616 process_attributes (Filedata * filedata,
18617 const char * public_name,
18618 unsigned int proc_type,
18619 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
18620 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
18622 Elf_Internal_Shdr * sect;
18623 unsigned i;
18624 bool res = true;
18626 /* Find the section header so that we get the size. */
18627 for (i = 0, sect = filedata->section_headers;
18628 i < filedata->file_header.e_shnum;
18629 i++, sect++)
18631 unsigned char * contents;
18632 unsigned char * p;
18634 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
18635 continue;
18637 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
18638 sect->sh_size, _("attributes"));
18639 if (contents == NULL)
18641 res = false;
18642 continue;
18645 p = contents;
18646 /* The first character is the version of the attributes.
18647 Currently only version 1, (aka 'A') is recognised here. */
18648 if (*p != 'A')
18650 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
18651 res = false;
18653 else
18655 uint64_t section_len;
18657 section_len = sect->sh_size - 1;
18658 p++;
18660 while (section_len > 0)
18662 uint64_t attr_len;
18663 unsigned int namelen;
18664 bool public_section;
18665 bool gnu_section;
18667 if (section_len <= 4)
18669 error (_("Tag section ends prematurely\n"));
18670 res = false;
18671 break;
18673 attr_len = byte_get (p, 4);
18674 p += 4;
18676 if (attr_len > section_len)
18678 error (_("Bad attribute length (%u > %u)\n"),
18679 (unsigned) attr_len, (unsigned) section_len);
18680 attr_len = section_len;
18681 res = false;
18683 /* PR 17531: file: 001-101425-0.004 */
18684 else if (attr_len < 5)
18686 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
18687 res = false;
18688 break;
18691 section_len -= attr_len;
18692 attr_len -= 4;
18694 namelen = strnlen ((char *) p, attr_len) + 1;
18695 if (namelen == 0 || namelen >= attr_len)
18697 error (_("Corrupt attribute section name\n"));
18698 res = false;
18699 break;
18702 printf (_("Attribute Section: "));
18703 print_symbol_name (INT_MAX, (const char *) p);
18704 putchar ('\n');
18706 if (public_name && streq ((char *) p, public_name))
18707 public_section = true;
18708 else
18709 public_section = false;
18711 if (streq ((char *) p, "gnu"))
18712 gnu_section = true;
18713 else
18714 gnu_section = false;
18716 p += namelen;
18717 attr_len -= namelen;
18719 while (attr_len > 0 && p < contents + sect->sh_size)
18721 int tag;
18722 unsigned int val;
18723 uint64_t size;
18724 unsigned char * end;
18726 /* PR binutils/17531: Safe handling of corrupt files. */
18727 if (attr_len < 6)
18729 error (_("Unused bytes at end of section\n"));
18730 res = false;
18731 section_len = 0;
18732 break;
18735 tag = *(p++);
18736 size = byte_get (p, 4);
18737 if (size > attr_len)
18739 error (_("Bad subsection length (%u > %u)\n"),
18740 (unsigned) size, (unsigned) attr_len);
18741 res = false;
18742 size = attr_len;
18744 /* PR binutils/17531: Safe handling of corrupt files. */
18745 if (size < 6)
18747 error (_("Bad subsection length (%u < 6)\n"),
18748 (unsigned) size);
18749 res = false;
18750 section_len = 0;
18751 break;
18754 attr_len -= size;
18755 end = p + size - 1;
18756 assert (end <= contents + sect->sh_size);
18757 p += 4;
18759 switch (tag)
18761 case 1:
18762 printf (_("File Attributes\n"));
18763 break;
18764 case 2:
18765 printf (_("Section Attributes:"));
18766 goto do_numlist;
18767 case 3:
18768 printf (_("Symbol Attributes:"));
18769 /* Fall through. */
18770 do_numlist:
18771 for (;;)
18773 READ_ULEB (val, p, end);
18774 if (val == 0)
18775 break;
18776 printf (" %d", val);
18778 printf ("\n");
18779 break;
18780 default:
18781 printf (_("Unknown tag: %d\n"), tag);
18782 public_section = false;
18783 break;
18786 if (public_section && display_pub_attribute != NULL)
18788 while (p < end)
18789 p = display_pub_attribute (p, end);
18790 assert (p == end);
18792 else if (gnu_section && display_proc_gnu_attribute != NULL)
18794 while (p < end)
18795 p = display_gnu_attribute (p,
18796 display_proc_gnu_attribute,
18797 end);
18798 assert (p == end);
18800 else if (p < end)
18802 printf (_(" Unknown attribute:\n"));
18803 display_raw_attribute (p, end);
18804 p = end;
18806 else
18807 attr_len = 0;
18812 free (contents);
18815 return res;
18818 /* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
18819 Print the Address, Access and Initial fields of an entry at VMA ADDR
18820 and return the VMA of the next entry, or -1 if there was a problem.
18821 Does not read from DATA_END or beyond. */
18823 static uint64_t
18824 print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
18825 unsigned char * data_end)
18827 printf (" ");
18828 print_vma (addr, LONG_HEX);
18829 printf (" ");
18830 if (addr < pltgot + 0xfff0)
18831 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
18832 else
18833 printf ("%10s", "");
18834 printf (" ");
18835 if (data == NULL)
18836 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
18837 else
18839 uint64_t entry;
18840 unsigned char * from = data + addr - pltgot;
18842 if (from + (is_32bit_elf ? 4 : 8) > data_end)
18844 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
18845 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
18846 return (uint64_t) -1;
18848 else
18850 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18851 print_vma (entry, LONG_HEX);
18854 return addr + (is_32bit_elf ? 4 : 8);
18857 /* DATA points to the contents of a MIPS PLT GOT that starts at VMA
18858 PLTGOT. Print the Address and Initial fields of an entry at VMA
18859 ADDR and return the VMA of the next entry. */
18861 static uint64_t
18862 print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
18864 printf (" ");
18865 print_vma (addr, LONG_HEX);
18866 printf (" ");
18867 if (data == NULL)
18868 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
18869 else
18871 uint64_t entry;
18873 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18874 print_vma (entry, LONG_HEX);
18876 return addr + (is_32bit_elf ? 4 : 8);
18879 static void
18880 print_mips_ases (unsigned int mask)
18882 if (mask & AFL_ASE_DSP)
18883 fputs ("\n\tDSP ASE", stdout);
18884 if (mask & AFL_ASE_DSPR2)
18885 fputs ("\n\tDSP R2 ASE", stdout);
18886 if (mask & AFL_ASE_DSPR3)
18887 fputs ("\n\tDSP R3 ASE", stdout);
18888 if (mask & AFL_ASE_EVA)
18889 fputs ("\n\tEnhanced VA Scheme", stdout);
18890 if (mask & AFL_ASE_MCU)
18891 fputs ("\n\tMCU (MicroController) ASE", stdout);
18892 if (mask & AFL_ASE_MDMX)
18893 fputs ("\n\tMDMX ASE", stdout);
18894 if (mask & AFL_ASE_MIPS3D)
18895 fputs ("\n\tMIPS-3D ASE", stdout);
18896 if (mask & AFL_ASE_MT)
18897 fputs ("\n\tMT ASE", stdout);
18898 if (mask & AFL_ASE_SMARTMIPS)
18899 fputs ("\n\tSmartMIPS ASE", stdout);
18900 if (mask & AFL_ASE_VIRT)
18901 fputs ("\n\tVZ ASE", stdout);
18902 if (mask & AFL_ASE_MSA)
18903 fputs ("\n\tMSA ASE", stdout);
18904 if (mask & AFL_ASE_MIPS16)
18905 fputs ("\n\tMIPS16 ASE", stdout);
18906 if (mask & AFL_ASE_MICROMIPS)
18907 fputs ("\n\tMICROMIPS ASE", stdout);
18908 if (mask & AFL_ASE_XPA)
18909 fputs ("\n\tXPA ASE", stdout);
18910 if (mask & AFL_ASE_MIPS16E2)
18911 fputs ("\n\tMIPS16e2 ASE", stdout);
18912 if (mask & AFL_ASE_CRC)
18913 fputs ("\n\tCRC ASE", stdout);
18914 if (mask & AFL_ASE_GINV)
18915 fputs ("\n\tGINV ASE", stdout);
18916 if (mask & AFL_ASE_LOONGSON_MMI)
18917 fputs ("\n\tLoongson MMI ASE", stdout);
18918 if (mask & AFL_ASE_LOONGSON_CAM)
18919 fputs ("\n\tLoongson CAM ASE", stdout);
18920 if (mask & AFL_ASE_LOONGSON_EXT)
18921 fputs ("\n\tLoongson EXT ASE", stdout);
18922 if (mask & AFL_ASE_LOONGSON_EXT2)
18923 fputs ("\n\tLoongson EXT2 ASE", stdout);
18924 if (mask == 0)
18925 fprintf (stdout, "\n\t%s", _("None"));
18926 else if ((mask & ~AFL_ASE_MASK) != 0)
18927 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
18930 static void
18931 print_mips_isa_ext (unsigned int isa_ext)
18933 switch (isa_ext)
18935 case 0:
18936 fputs (_("None"), stdout);
18937 break;
18938 case AFL_EXT_XLR:
18939 fputs ("RMI XLR", stdout);
18940 break;
18941 case AFL_EXT_OCTEON3:
18942 fputs ("Cavium Networks Octeon3", stdout);
18943 break;
18944 case AFL_EXT_OCTEON2:
18945 fputs ("Cavium Networks Octeon2", stdout);
18946 break;
18947 case AFL_EXT_OCTEONP:
18948 fputs ("Cavium Networks OcteonP", stdout);
18949 break;
18950 case AFL_EXT_OCTEON:
18951 fputs ("Cavium Networks Octeon", stdout);
18952 break;
18953 case AFL_EXT_5900:
18954 fputs ("Toshiba R5900", stdout);
18955 break;
18956 case AFL_EXT_4650:
18957 fputs ("MIPS R4650", stdout);
18958 break;
18959 case AFL_EXT_4010:
18960 fputs ("LSI R4010", stdout);
18961 break;
18962 case AFL_EXT_4100:
18963 fputs ("NEC VR4100", stdout);
18964 break;
18965 case AFL_EXT_3900:
18966 fputs ("Toshiba R3900", stdout);
18967 break;
18968 case AFL_EXT_10000:
18969 fputs ("MIPS R10000", stdout);
18970 break;
18971 case AFL_EXT_SB1:
18972 fputs ("Broadcom SB-1", stdout);
18973 break;
18974 case AFL_EXT_4111:
18975 fputs ("NEC VR4111/VR4181", stdout);
18976 break;
18977 case AFL_EXT_4120:
18978 fputs ("NEC VR4120", stdout);
18979 break;
18980 case AFL_EXT_5400:
18981 fputs ("NEC VR5400", stdout);
18982 break;
18983 case AFL_EXT_5500:
18984 fputs ("NEC VR5500", stdout);
18985 break;
18986 case AFL_EXT_LOONGSON_2E:
18987 fputs ("ST Microelectronics Loongson 2E", stdout);
18988 break;
18989 case AFL_EXT_LOONGSON_2F:
18990 fputs ("ST Microelectronics Loongson 2F", stdout);
18991 break;
18992 case AFL_EXT_INTERAPTIV_MR2:
18993 fputs ("Imagination interAptiv MR2", stdout);
18994 break;
18995 default:
18996 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
19000 static signed int
19001 get_mips_reg_size (int reg_size)
19003 return (reg_size == AFL_REG_NONE) ? 0
19004 : (reg_size == AFL_REG_32) ? 32
19005 : (reg_size == AFL_REG_64) ? 64
19006 : (reg_size == AFL_REG_128) ? 128
19007 : -1;
19010 static bool
19011 process_mips_specific (Filedata * filedata)
19013 Elf_Internal_Dyn * entry;
19014 Elf_Internal_Shdr *sect = NULL;
19015 size_t liblist_offset = 0;
19016 size_t liblistno = 0;
19017 size_t conflictsno = 0;
19018 size_t options_offset = 0;
19019 size_t conflicts_offset = 0;
19020 size_t pltrelsz = 0;
19021 size_t pltrel = 0;
19022 uint64_t pltgot = 0;
19023 uint64_t mips_pltgot = 0;
19024 uint64_t jmprel = 0;
19025 uint64_t local_gotno = 0;
19026 uint64_t gotsym = 0;
19027 uint64_t symtabno = 0;
19028 bool res = true;
19030 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
19031 display_mips_gnu_attribute))
19032 res = false;
19034 sect = find_section (filedata, ".MIPS.abiflags");
19036 if (sect != NULL)
19038 Elf_External_ABIFlags_v0 *abiflags_ext;
19039 Elf_Internal_ABIFlags_v0 abiflags_in;
19041 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
19043 error (_("Corrupt MIPS ABI Flags section.\n"));
19044 res = false;
19046 else
19048 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
19049 sect->sh_size, _("MIPS ABI Flags section"));
19050 if (abiflags_ext)
19052 abiflags_in.version = BYTE_GET (abiflags_ext->version);
19053 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
19054 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
19055 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
19056 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
19057 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
19058 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
19059 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
19060 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
19061 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
19062 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
19064 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
19065 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
19066 if (abiflags_in.isa_rev > 1)
19067 printf ("r%d", abiflags_in.isa_rev);
19068 printf ("\nGPR size: %d",
19069 get_mips_reg_size (abiflags_in.gpr_size));
19070 printf ("\nCPR1 size: %d",
19071 get_mips_reg_size (abiflags_in.cpr1_size));
19072 printf ("\nCPR2 size: %d",
19073 get_mips_reg_size (abiflags_in.cpr2_size));
19074 fputs ("\nFP ABI: ", stdout);
19075 print_mips_fp_abi_value (abiflags_in.fp_abi);
19076 fputs ("ISA Extension: ", stdout);
19077 print_mips_isa_ext (abiflags_in.isa_ext);
19078 fputs ("\nASEs:", stdout);
19079 print_mips_ases (abiflags_in.ases);
19080 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
19081 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
19082 fputc ('\n', stdout);
19083 free (abiflags_ext);
19088 /* We have a lot of special sections. Thanks SGI! */
19089 if (filedata->dynamic_section == NULL)
19091 /* No dynamic information available. See if there is static GOT. */
19092 sect = find_section (filedata, ".got");
19093 if (sect != NULL)
19095 unsigned char *data_end;
19096 unsigned char *data;
19097 uint64_t ent, end;
19098 int addr_size;
19100 pltgot = sect->sh_addr;
19102 ent = pltgot;
19103 addr_size = (is_32bit_elf ? 4 : 8);
19104 end = pltgot + sect->sh_size;
19106 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
19107 end - pltgot, 1,
19108 _("Global Offset Table data"));
19109 /* PR 12855: Null data is handled gracefully throughout. */
19110 data_end = data + (end - pltgot);
19112 printf (_("\nStatic GOT:\n"));
19113 printf (_(" Canonical gp value: "));
19114 print_vma (ent + 0x7ff0, LONG_HEX);
19115 printf ("\n\n");
19117 /* In a dynamic binary GOT[0] is reserved for the dynamic
19118 loader to store the lazy resolver pointer, however in
19119 a static binary it may well have been omitted and GOT
19120 reduced to a table of addresses.
19121 PR 21344: Check for the entry being fully available
19122 before fetching it. */
19123 if (data
19124 && data + ent - pltgot + addr_size <= data_end
19125 && byte_get (data + ent - pltgot, addr_size) == 0)
19127 printf (_(" Reserved entries:\n"));
19128 printf (_(" %*s %10s %*s\n"),
19129 addr_size * 2, _("Address"), _("Access"),
19130 addr_size * 2, _("Value"));
19131 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19132 printf ("\n");
19133 if (ent == (uint64_t) -1)
19134 goto sgot_print_fail;
19136 /* Check for the MSB of GOT[1] being set, identifying a
19137 GNU object. This entry will be used by some runtime
19138 loaders, to store the module pointer. Otherwise this
19139 is an ordinary local entry.
19140 PR 21344: Check for the entry being fully available
19141 before fetching it. */
19142 if (data
19143 && data + ent - pltgot + addr_size <= data_end
19144 && (byte_get (data + ent - pltgot, addr_size)
19145 >> (addr_size * 8 - 1)) != 0)
19147 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19148 printf ("\n");
19149 if (ent == (uint64_t) -1)
19150 goto sgot_print_fail;
19152 printf ("\n");
19155 if (data != NULL && ent < end)
19157 printf (_(" Local entries:\n"));
19158 printf (" %*s %10s %*s\n",
19159 addr_size * 2, _("Address"), _("Access"),
19160 addr_size * 2, _("Value"));
19161 while (ent < end)
19163 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19164 printf ("\n");
19165 if (ent == (uint64_t) -1)
19166 goto sgot_print_fail;
19168 printf ("\n");
19171 sgot_print_fail:
19172 free (data);
19174 return res;
19177 for (entry = filedata->dynamic_section;
19178 /* PR 17531 file: 012-50589-0.004. */
19179 (entry < filedata->dynamic_section + filedata->dynamic_nent
19180 && entry->d_tag != DT_NULL);
19181 ++entry)
19182 switch (entry->d_tag)
19184 case DT_MIPS_LIBLIST:
19185 liblist_offset
19186 = offset_from_vma (filedata, entry->d_un.d_val,
19187 liblistno * sizeof (Elf32_External_Lib));
19188 break;
19189 case DT_MIPS_LIBLISTNO:
19190 liblistno = entry->d_un.d_val;
19191 break;
19192 case DT_MIPS_OPTIONS:
19193 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
19194 break;
19195 case DT_MIPS_CONFLICT:
19196 conflicts_offset
19197 = offset_from_vma (filedata, entry->d_un.d_val,
19198 conflictsno * sizeof (Elf32_External_Conflict));
19199 break;
19200 case DT_MIPS_CONFLICTNO:
19201 conflictsno = entry->d_un.d_val;
19202 break;
19203 case DT_PLTGOT:
19204 pltgot = entry->d_un.d_ptr;
19205 break;
19206 case DT_MIPS_LOCAL_GOTNO:
19207 local_gotno = entry->d_un.d_val;
19208 break;
19209 case DT_MIPS_GOTSYM:
19210 gotsym = entry->d_un.d_val;
19211 break;
19212 case DT_MIPS_SYMTABNO:
19213 symtabno = entry->d_un.d_val;
19214 break;
19215 case DT_MIPS_PLTGOT:
19216 mips_pltgot = entry->d_un.d_ptr;
19217 break;
19218 case DT_PLTREL:
19219 pltrel = entry->d_un.d_val;
19220 break;
19221 case DT_PLTRELSZ:
19222 pltrelsz = entry->d_un.d_val;
19223 break;
19224 case DT_JMPREL:
19225 jmprel = entry->d_un.d_ptr;
19226 break;
19227 default:
19228 break;
19231 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
19233 Elf32_External_Lib * elib;
19234 size_t cnt;
19236 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
19237 sizeof (Elf32_External_Lib),
19238 liblistno,
19239 _("liblist section data"));
19240 if (elib)
19242 printf (ngettext ("\nSection '.liblist' contains %zu entry:\n",
19243 "\nSection '.liblist' contains %zu entries:\n",
19244 liblistno),
19245 liblistno);
19246 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
19247 stdout);
19249 for (cnt = 0; cnt < liblistno; ++cnt)
19251 Elf32_Lib liblist;
19252 time_t atime;
19253 char timebuf[128];
19254 struct tm * tmp;
19256 liblist.l_name = BYTE_GET (elib[cnt].l_name);
19257 atime = BYTE_GET (elib[cnt].l_time_stamp);
19258 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19259 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19260 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19262 tmp = gmtime (&atime);
19263 snprintf (timebuf, sizeof (timebuf),
19264 "%04u-%02u-%02uT%02u:%02u:%02u",
19265 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19266 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
19268 printf ("%3zu: ", cnt);
19269 if (valid_dynamic_name (filedata, liblist.l_name))
19270 print_symbol_name (20, get_dynamic_name (filedata, liblist.l_name));
19271 else
19272 printf (_("<corrupt: %9ld>"), liblist.l_name);
19273 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
19274 liblist.l_version);
19276 if (liblist.l_flags == 0)
19277 puts (_(" NONE"));
19278 else
19280 static const struct
19282 const char * name;
19283 int bit;
19285 l_flags_vals[] =
19287 { " EXACT_MATCH", LL_EXACT_MATCH },
19288 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
19289 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
19290 { " EXPORTS", LL_EXPORTS },
19291 { " DELAY_LOAD", LL_DELAY_LOAD },
19292 { " DELTA", LL_DELTA }
19294 int flags = liblist.l_flags;
19295 size_t fcnt;
19297 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
19298 if ((flags & l_flags_vals[fcnt].bit) != 0)
19300 fputs (l_flags_vals[fcnt].name, stdout);
19301 flags ^= l_flags_vals[fcnt].bit;
19303 if (flags != 0)
19304 printf (" %#x", (unsigned int) flags);
19306 puts ("");
19310 free (elib);
19312 else
19313 res = false;
19316 if (options_offset != 0)
19318 Elf_External_Options * eopt;
19319 size_t offset;
19320 int cnt;
19322 /* Find the section header so that we get the size. */
19323 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
19324 /* PR 17533 file: 012-277276-0.004. */
19325 if (sect == NULL)
19327 error (_("No MIPS_OPTIONS header found\n"));
19328 return false;
19330 /* PR 24243 */
19331 if (sect->sh_size < sizeof (* eopt))
19333 error (_("The MIPS options section is too small.\n"));
19334 return false;
19337 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
19338 sect->sh_size, _("options"));
19339 if (eopt)
19341 Elf_Internal_Options option;
19343 offset = cnt = 0;
19344 while (offset <= sect->sh_size - sizeof (* eopt))
19346 Elf_External_Options * eoption;
19347 unsigned int optsize;
19349 eoption = (Elf_External_Options *) ((char *) eopt + offset);
19351 optsize = BYTE_GET (eoption->size);
19353 /* PR 17531: file: ffa0fa3b. */
19354 if (optsize < sizeof (* eopt)
19355 || optsize > sect->sh_size - offset)
19357 error (_("Invalid size (%u) for MIPS option\n"),
19358 optsize);
19359 free (eopt);
19360 return false;
19362 offset += optsize;
19363 ++cnt;
19366 printf (ngettext ("\nSection '%s' contains %d entry:\n",
19367 "\nSection '%s' contains %d entries:\n",
19368 cnt),
19369 printable_section_name (filedata, sect), cnt);
19371 offset = 0;
19372 while (cnt-- > 0)
19374 size_t len;
19375 Elf_External_Options * eoption;
19377 eoption = (Elf_External_Options *) ((char *) eopt + offset);
19379 option.kind = BYTE_GET (eoption->kind);
19380 option.size = BYTE_GET (eoption->size);
19381 option.section = BYTE_GET (eoption->section);
19382 option.info = BYTE_GET (eoption->info);
19384 switch (option.kind)
19386 case ODK_NULL:
19387 /* This shouldn't happen. */
19388 printf (" NULL %" PRId16 " %" PRIx32,
19389 option.section, option.info);
19390 break;
19392 case ODK_REGINFO:
19393 printf (" REGINFO ");
19394 if (filedata->file_header.e_machine == EM_MIPS)
19396 Elf32_External_RegInfo * ereg;
19397 Elf32_RegInfo reginfo;
19399 /* 32bit form. */
19400 if (option.size < (sizeof (Elf_External_Options)
19401 + sizeof (Elf32_External_RegInfo)))
19403 printf (_("<corrupt>\n"));
19404 error (_("Truncated MIPS REGINFO option\n"));
19405 cnt = 0;
19406 break;
19409 ereg = (Elf32_External_RegInfo *) (eoption + 1);
19411 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
19412 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
19413 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
19414 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
19415 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
19416 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
19418 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
19419 reginfo.ri_gprmask, reginfo.ri_gp_value);
19420 printf (" "
19421 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
19422 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
19423 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
19424 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
19426 else
19428 /* 64 bit form. */
19429 Elf64_External_RegInfo * ereg;
19430 Elf64_Internal_RegInfo reginfo;
19432 if (option.size < (sizeof (Elf_External_Options)
19433 + sizeof (Elf64_External_RegInfo)))
19435 printf (_("<corrupt>\n"));
19436 error (_("Truncated MIPS REGINFO option\n"));
19437 cnt = 0;
19438 break;
19441 ereg = (Elf64_External_RegInfo *) (eoption + 1);
19442 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
19443 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
19444 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
19445 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
19446 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
19447 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
19449 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
19450 reginfo.ri_gprmask, reginfo.ri_gp_value);
19451 printf (" "
19452 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
19453 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
19454 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
19455 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
19457 offset += option.size;
19458 continue;
19460 case ODK_EXCEPTIONS:
19461 fputs (" EXCEPTIONS fpe_min(", stdout);
19462 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
19463 fputs (") fpe_max(", stdout);
19464 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
19465 fputs (")", stdout);
19467 if (option.info & OEX_PAGE0)
19468 fputs (" PAGE0", stdout);
19469 if (option.info & OEX_SMM)
19470 fputs (" SMM", stdout);
19471 if (option.info & OEX_FPDBUG)
19472 fputs (" FPDBUG", stdout);
19473 if (option.info & OEX_DISMISS)
19474 fputs (" DISMISS", stdout);
19475 break;
19477 case ODK_PAD:
19478 fputs (" PAD ", stdout);
19479 if (option.info & OPAD_PREFIX)
19480 fputs (" PREFIX", stdout);
19481 if (option.info & OPAD_POSTFIX)
19482 fputs (" POSTFIX", stdout);
19483 if (option.info & OPAD_SYMBOL)
19484 fputs (" SYMBOL", stdout);
19485 break;
19487 case ODK_HWPATCH:
19488 fputs (" HWPATCH ", stdout);
19489 if (option.info & OHW_R4KEOP)
19490 fputs (" R4KEOP", stdout);
19491 if (option.info & OHW_R8KPFETCH)
19492 fputs (" R8KPFETCH", stdout);
19493 if (option.info & OHW_R5KEOP)
19494 fputs (" R5KEOP", stdout);
19495 if (option.info & OHW_R5KCVTL)
19496 fputs (" R5KCVTL", stdout);
19497 break;
19499 case ODK_FILL:
19500 fputs (" FILL ", stdout);
19501 /* XXX Print content of info word? */
19502 break;
19504 case ODK_TAGS:
19505 fputs (" TAGS ", stdout);
19506 /* XXX Print content of info word? */
19507 break;
19509 case ODK_HWAND:
19510 fputs (" HWAND ", stdout);
19511 if (option.info & OHWA0_R4KEOP_CHECKED)
19512 fputs (" R4KEOP_CHECKED", stdout);
19513 if (option.info & OHWA0_R4KEOP_CLEAN)
19514 fputs (" R4KEOP_CLEAN", stdout);
19515 break;
19517 case ODK_HWOR:
19518 fputs (" HWOR ", stdout);
19519 if (option.info & OHWA0_R4KEOP_CHECKED)
19520 fputs (" R4KEOP_CHECKED", stdout);
19521 if (option.info & OHWA0_R4KEOP_CLEAN)
19522 fputs (" R4KEOP_CLEAN", stdout);
19523 break;
19525 case ODK_GP_GROUP:
19526 printf (" GP_GROUP %#06x self-contained %#06x",
19527 option.info & OGP_GROUP,
19528 (option.info & OGP_SELF) >> 16);
19529 break;
19531 case ODK_IDENT:
19532 printf (" IDENT %#06x self-contained %#06x",
19533 option.info & OGP_GROUP,
19534 (option.info & OGP_SELF) >> 16);
19535 break;
19537 default:
19538 /* This shouldn't happen. */
19539 printf (" %3d ??? %" PRId16 " %" PRIx32,
19540 option.kind, option.section, option.info);
19541 break;
19544 len = sizeof (* eopt);
19545 while (len < option.size)
19547 unsigned char datum = *((unsigned char *) eoption + len);
19549 if (ISPRINT (datum))
19550 printf ("%c", datum);
19551 else
19552 printf ("\\%03o", datum);
19553 len ++;
19555 fputs ("\n", stdout);
19557 offset += option.size;
19559 free (eopt);
19561 else
19562 res = false;
19565 if (conflicts_offset != 0 && conflictsno != 0)
19567 Elf32_Conflict * iconf;
19568 size_t cnt;
19570 if (filedata->dynamic_symbols == NULL)
19572 error (_("conflict list found without a dynamic symbol table\n"));
19573 return false;
19576 /* PR 21345 - print a slightly more helpful error message
19577 if we are sure that the cmalloc will fail. */
19578 if (conflictsno > filedata->file_size / sizeof (* iconf))
19580 error (_("Overlarge number of conflicts detected: %zx\n"),
19581 conflictsno);
19582 return false;
19585 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
19586 if (iconf == NULL)
19588 error (_("Out of memory allocating space for dynamic conflicts\n"));
19589 return false;
19592 if (is_32bit_elf)
19594 Elf32_External_Conflict * econf32;
19596 econf32 = (Elf32_External_Conflict *)
19597 get_data (NULL, filedata, conflicts_offset,
19598 sizeof (*econf32), conflictsno, _("conflict"));
19599 if (!econf32)
19601 free (iconf);
19602 return false;
19605 for (cnt = 0; cnt < conflictsno; ++cnt)
19606 iconf[cnt] = BYTE_GET (econf32[cnt]);
19608 free (econf32);
19610 else
19612 Elf64_External_Conflict * econf64;
19614 econf64 = (Elf64_External_Conflict *)
19615 get_data (NULL, filedata, conflicts_offset,
19616 sizeof (*econf64), conflictsno, _("conflict"));
19617 if (!econf64)
19619 free (iconf);
19620 return false;
19623 for (cnt = 0; cnt < conflictsno; ++cnt)
19624 iconf[cnt] = BYTE_GET (econf64[cnt]);
19626 free (econf64);
19629 printf (ngettext ("\nSection '.conflict' contains %zu entry:\n",
19630 "\nSection '.conflict' contains %zu entries:\n",
19631 conflictsno),
19632 conflictsno);
19633 puts (_(" Num: Index Value Name"));
19635 for (cnt = 0; cnt < conflictsno; ++cnt)
19637 printf ("%5zu: %8lu ", cnt, iconf[cnt]);
19639 if (iconf[cnt] >= filedata->num_dynamic_syms)
19640 printf (_("<corrupt symbol index>"));
19641 else
19643 Elf_Internal_Sym * psym;
19645 psym = & filedata->dynamic_symbols[iconf[cnt]];
19646 print_vma (psym->st_value, FULL_HEX);
19647 putchar (' ');
19648 if (valid_dynamic_name (filedata, psym->st_name))
19649 print_symbol_name (25, get_dynamic_name (filedata, psym->st_name));
19650 else
19651 printf (_("<corrupt: %14ld>"), psym->st_name);
19653 putchar ('\n');
19656 free (iconf);
19659 if (pltgot != 0 && local_gotno != 0)
19661 uint64_t ent, local_end, global_end;
19662 size_t i, offset;
19663 unsigned char * data;
19664 unsigned char * data_end;
19665 int addr_size;
19667 ent = pltgot;
19668 addr_size = (is_32bit_elf ? 4 : 8);
19669 local_end = pltgot + local_gotno * addr_size;
19671 /* PR binutils/17533 file: 012-111227-0.004 */
19672 if (symtabno < gotsym)
19674 error (_("The GOT symbol offset (%" PRIu64
19675 ") is greater than the symbol table size (%" PRIu64 ")\n"),
19676 gotsym, symtabno);
19677 return false;
19680 global_end = local_end + (symtabno - gotsym) * addr_size;
19681 /* PR 17531: file: 54c91a34. */
19682 if (global_end < local_end)
19684 error (_("Too many GOT symbols: %" PRIu64 "\n"), symtabno);
19685 return false;
19688 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
19689 data = (unsigned char *) get_data (NULL, filedata, offset,
19690 global_end - pltgot, 1,
19691 _("Global Offset Table data"));
19692 /* PR 12855: Null data is handled gracefully throughout. */
19693 data_end = data + (global_end - pltgot);
19695 printf (_("\nPrimary GOT:\n"));
19696 printf (_(" Canonical gp value: "));
19697 print_vma (pltgot + 0x7ff0, LONG_HEX);
19698 printf ("\n\n");
19700 printf (_(" Reserved entries:\n"));
19701 printf (_(" %*s %10s %*s Purpose\n"),
19702 addr_size * 2, _("Address"), _("Access"),
19703 addr_size * 2, _("Initial"));
19704 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19705 printf (_(" Lazy resolver\n"));
19706 if (ent == (uint64_t) -1)
19707 goto got_print_fail;
19709 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
19710 This entry will be used by some runtime loaders, to store the
19711 module pointer. Otherwise this is an ordinary local entry.
19712 PR 21344: Check for the entry being fully available before
19713 fetching it. */
19714 if (data
19715 && data + ent - pltgot + addr_size <= data_end
19716 && (byte_get (data + ent - pltgot, addr_size)
19717 >> (addr_size * 8 - 1)) != 0)
19719 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19720 printf (_(" Module pointer (GNU extension)\n"));
19721 if (ent == (uint64_t) -1)
19722 goto got_print_fail;
19724 printf ("\n");
19726 if (data != NULL && ent < local_end)
19728 printf (_(" Local entries:\n"));
19729 printf (" %*s %10s %*s\n",
19730 addr_size * 2, _("Address"), _("Access"),
19731 addr_size * 2, _("Initial"));
19732 while (ent < local_end)
19734 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19735 printf ("\n");
19736 if (ent == (uint64_t) -1)
19737 goto got_print_fail;
19739 printf ("\n");
19742 if (data != NULL && gotsym < symtabno)
19744 int sym_width;
19746 printf (_(" Global entries:\n"));
19747 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
19748 addr_size * 2, _("Address"),
19749 _("Access"),
19750 addr_size * 2, _("Initial"),
19751 addr_size * 2, _("Sym.Val."),
19752 _("Type"),
19753 /* Note for translators: "Ndx" = abbreviated form of "Index". */
19754 _("Ndx"), _("Name"));
19756 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
19758 for (i = gotsym; i < symtabno; i++)
19760 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19761 printf (" ");
19763 if (filedata->dynamic_symbols == NULL)
19764 printf (_("<no dynamic symbols>"));
19765 else if (i < filedata->num_dynamic_syms)
19767 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
19769 print_vma (psym->st_value, LONG_HEX);
19770 printf (" %-7s ", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
19772 bool is_special;
19773 const char * s = printable_section_name_from_index (filedata, psym->st_shndx, & is_special);
19774 if (is_special)
19775 printf ("%3s ", s);
19776 else
19777 printf ("%3u ", psym->st_shndx);
19779 if (valid_dynamic_name (filedata, psym->st_name))
19780 print_symbol_name (sym_width,
19781 get_dynamic_name (filedata, psym->st_name));
19782 else
19783 printf (_("<corrupt: %14ld>"), psym->st_name);
19785 else
19786 printf (_("<symbol index %zu exceeds number of dynamic symbols>"),
19789 printf ("\n");
19790 if (ent == (uint64_t) -1)
19791 break;
19793 printf ("\n");
19796 got_print_fail:
19797 free (data);
19800 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
19802 uint64_t ent, end;
19803 uint64_t offset, rel_offset;
19804 uint64_t count, i;
19805 unsigned char * data;
19806 int addr_size, sym_width;
19807 Elf_Internal_Rela * rels;
19809 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
19810 if (pltrel == DT_RELA)
19812 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
19813 return false;
19815 else
19817 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
19818 return false;
19821 ent = mips_pltgot;
19822 addr_size = (is_32bit_elf ? 4 : 8);
19823 end = mips_pltgot + (2 + count) * addr_size;
19825 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
19826 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
19827 1, _("Procedure Linkage Table data"));
19828 if (data == NULL)
19830 free (rels);
19831 return false;
19834 printf ("\nPLT GOT:\n\n");
19835 printf (_(" Reserved entries:\n"));
19836 printf (_(" %*s %*s Purpose\n"),
19837 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
19838 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
19839 printf (_(" PLT lazy resolver\n"));
19840 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
19841 printf (_(" Module pointer\n"));
19842 printf ("\n");
19844 printf (_(" Entries:\n"));
19845 printf (" %*s %*s %*s %-7s %3s %s\n",
19846 addr_size * 2, _("Address"),
19847 addr_size * 2, _("Initial"),
19848 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
19849 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
19850 for (i = 0; i < count; i++)
19852 uint64_t idx = get_reloc_symindex (rels[i].r_info);
19854 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
19855 printf (" ");
19857 if (idx >= filedata->num_dynamic_syms)
19858 printf (_("<corrupt symbol index: %" PRIu64 ">"), idx);
19859 else
19861 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
19863 print_vma (psym->st_value, LONG_HEX);
19864 printf (" %-7s %3s ",
19865 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19866 printable_section_name_from_index (filedata, psym->st_shndx, NULL));
19867 if (valid_dynamic_name (filedata, psym->st_name))
19868 print_symbol_name (sym_width,
19869 get_dynamic_name (filedata, psym->st_name));
19870 else
19871 printf (_("<corrupt: %14ld>"), psym->st_name);
19873 printf ("\n");
19875 printf ("\n");
19877 free (data);
19878 free (rels);
19881 return res;
19884 static bool
19885 process_nds32_specific (Filedata * filedata)
19887 Elf_Internal_Shdr *sect = NULL;
19889 sect = find_section (filedata, ".nds32_e_flags");
19890 if (sect != NULL && sect->sh_size >= 4)
19892 unsigned char *buf;
19893 unsigned int flag;
19895 printf ("\nNDS32 elf flags section:\n");
19896 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
19897 _("NDS32 elf flags section"));
19899 if (buf == NULL)
19900 return false;
19902 flag = byte_get (buf, 4);
19903 free (buf);
19904 switch (flag & 0x3)
19906 case 0:
19907 printf ("(VEC_SIZE):\tNo entry.\n");
19908 break;
19909 case 1:
19910 printf ("(VEC_SIZE):\t4 bytes\n");
19911 break;
19912 case 2:
19913 printf ("(VEC_SIZE):\t16 bytes\n");
19914 break;
19915 case 3:
19916 printf ("(VEC_SIZE):\treserved\n");
19917 break;
19921 return true;
19924 static bool
19925 process_gnu_liblist (Filedata * filedata)
19927 Elf_Internal_Shdr * section;
19928 Elf_Internal_Shdr * string_sec;
19929 Elf32_External_Lib * elib;
19930 char * strtab;
19931 size_t strtab_size;
19932 size_t cnt;
19933 uint64_t num_liblist;
19934 unsigned i;
19935 bool res = true;
19937 if (! do_arch)
19938 return true;
19940 for (i = 0, section = filedata->section_headers;
19941 i < filedata->file_header.e_shnum;
19942 i++, section++)
19944 switch (section->sh_type)
19946 case SHT_GNU_LIBLIST:
19947 if (section->sh_link >= filedata->file_header.e_shnum)
19948 break;
19950 elib = (Elf32_External_Lib *)
19951 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
19952 _("liblist section data"));
19954 if (elib == NULL)
19956 res = false;
19957 break;
19960 string_sec = filedata->section_headers + section->sh_link;
19961 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
19962 string_sec->sh_size,
19963 _("liblist string table"));
19964 if (strtab == NULL
19965 || section->sh_entsize != sizeof (Elf32_External_Lib))
19967 free (elib);
19968 free (strtab);
19969 res = false;
19970 break;
19972 strtab_size = string_sec->sh_size;
19974 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
19975 printf (ngettext ("\nLibrary list section '%s' contains %" PRIu64
19976 " entries:\n",
19977 "\nLibrary list section '%s' contains %" PRIu64
19978 " entries:\n",
19979 num_liblist),
19980 printable_section_name (filedata, section),
19981 num_liblist);
19983 puts (_(" Library Time Stamp Checksum Version Flags"));
19985 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19986 ++cnt)
19988 Elf32_Lib liblist;
19989 time_t atime;
19990 char timebuf[128];
19991 struct tm * tmp;
19993 liblist.l_name = BYTE_GET (elib[cnt].l_name);
19994 atime = BYTE_GET (elib[cnt].l_time_stamp);
19995 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19996 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19997 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19999 tmp = gmtime (&atime);
20000 snprintf (timebuf, sizeof (timebuf),
20001 "%04u-%02u-%02uT%02u:%02u:%02u",
20002 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
20003 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
20005 printf ("%3zu: ", cnt);
20006 if (do_wide)
20007 printf ("%-20s", liblist.l_name < strtab_size
20008 ? strtab + liblist.l_name : _("<corrupt>"));
20009 else
20010 printf ("%-20.20s", liblist.l_name < strtab_size
20011 ? strtab + liblist.l_name : _("<corrupt>"));
20012 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
20013 liblist.l_version, liblist.l_flags);
20016 free (elib);
20017 free (strtab);
20021 return res;
20024 static const char *
20025 get_note_type (Filedata * filedata, unsigned e_type)
20027 static char buff[64];
20029 if (filedata->file_header.e_type == ET_CORE)
20030 switch (e_type)
20032 case NT_AUXV:
20033 return _("NT_AUXV (auxiliary vector)");
20034 case NT_PRSTATUS:
20035 return _("NT_PRSTATUS (prstatus structure)");
20036 case NT_FPREGSET:
20037 return _("NT_FPREGSET (floating point registers)");
20038 case NT_PRPSINFO:
20039 return _("NT_PRPSINFO (prpsinfo structure)");
20040 case NT_TASKSTRUCT:
20041 return _("NT_TASKSTRUCT (task structure)");
20042 case NT_GDB_TDESC:
20043 return _("NT_GDB_TDESC (GDB XML target description)");
20044 case NT_PRXFPREG:
20045 return _("NT_PRXFPREG (user_xfpregs structure)");
20046 case NT_PPC_VMX:
20047 return _("NT_PPC_VMX (ppc Altivec registers)");
20048 case NT_PPC_VSX:
20049 return _("NT_PPC_VSX (ppc VSX registers)");
20050 case NT_PPC_TAR:
20051 return _("NT_PPC_TAR (ppc TAR register)");
20052 case NT_PPC_PPR:
20053 return _("NT_PPC_PPR (ppc PPR register)");
20054 case NT_PPC_DSCR:
20055 return _("NT_PPC_DSCR (ppc DSCR register)");
20056 case NT_PPC_EBB:
20057 return _("NT_PPC_EBB (ppc EBB registers)");
20058 case NT_PPC_PMU:
20059 return _("NT_PPC_PMU (ppc PMU registers)");
20060 case NT_PPC_TM_CGPR:
20061 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
20062 case NT_PPC_TM_CFPR:
20063 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
20064 case NT_PPC_TM_CVMX:
20065 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
20066 case NT_PPC_TM_CVSX:
20067 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
20068 case NT_PPC_TM_SPR:
20069 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
20070 case NT_PPC_TM_CTAR:
20071 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
20072 case NT_PPC_TM_CPPR:
20073 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
20074 case NT_PPC_TM_CDSCR:
20075 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
20076 case NT_386_TLS:
20077 return _("NT_386_TLS (x86 TLS information)");
20078 case NT_386_IOPERM:
20079 return _("NT_386_IOPERM (x86 I/O permissions)");
20080 case NT_X86_XSTATE:
20081 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
20082 case NT_X86_CET:
20083 return _("NT_X86_CET (x86 CET state)");
20084 case NT_X86_SHSTK:
20085 return _("NT_X86_SHSTK (x86 SHSTK state)");
20086 case NT_S390_HIGH_GPRS:
20087 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
20088 case NT_S390_TIMER:
20089 return _("NT_S390_TIMER (s390 timer register)");
20090 case NT_S390_TODCMP:
20091 return _("NT_S390_TODCMP (s390 TOD comparator register)");
20092 case NT_S390_TODPREG:
20093 return _("NT_S390_TODPREG (s390 TOD programmable register)");
20094 case NT_S390_CTRS:
20095 return _("NT_S390_CTRS (s390 control registers)");
20096 case NT_S390_PREFIX:
20097 return _("NT_S390_PREFIX (s390 prefix register)");
20098 case NT_S390_LAST_BREAK:
20099 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
20100 case NT_S390_SYSTEM_CALL:
20101 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
20102 case NT_S390_TDB:
20103 return _("NT_S390_TDB (s390 transaction diagnostic block)");
20104 case NT_S390_VXRS_LOW:
20105 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
20106 case NT_S390_VXRS_HIGH:
20107 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
20108 case NT_S390_GS_CB:
20109 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
20110 case NT_S390_GS_BC:
20111 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
20112 case NT_ARM_VFP:
20113 return _("NT_ARM_VFP (arm VFP registers)");
20114 case NT_ARM_TLS:
20115 return _("NT_ARM_TLS (AArch TLS registers)");
20116 case NT_ARM_HW_BREAK:
20117 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
20118 case NT_ARM_HW_WATCH:
20119 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
20120 case NT_ARM_SYSTEM_CALL:
20121 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
20122 case NT_ARM_SVE:
20123 return _("NT_ARM_SVE (AArch SVE registers)");
20124 case NT_ARM_PAC_MASK:
20125 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
20126 case NT_ARM_PACA_KEYS:
20127 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
20128 case NT_ARM_PACG_KEYS:
20129 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
20130 case NT_ARM_TAGGED_ADDR_CTRL:
20131 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
20132 case NT_ARM_SSVE:
20133 return _("NT_ARM_SSVE (AArch64 streaming SVE registers)");
20134 case NT_ARM_ZA:
20135 return _("NT_ARM_ZA (AArch64 SME ZA register)");
20136 case NT_ARM_ZT:
20137 return _("NT_ARM_ZT (AArch64 SME2 ZT registers)");
20138 case NT_ARM_PAC_ENABLED_KEYS:
20139 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
20140 case NT_ARC_V2:
20141 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
20142 case NT_RISCV_CSR:
20143 return _("NT_RISCV_CSR (RISC-V control and status registers)");
20144 case NT_PSTATUS:
20145 return _("NT_PSTATUS (pstatus structure)");
20146 case NT_FPREGS:
20147 return _("NT_FPREGS (floating point registers)");
20148 case NT_PSINFO:
20149 return _("NT_PSINFO (psinfo structure)");
20150 case NT_LWPSTATUS:
20151 return _("NT_LWPSTATUS (lwpstatus_t structure)");
20152 case NT_LWPSINFO:
20153 return _("NT_LWPSINFO (lwpsinfo_t structure)");
20154 case NT_WIN32PSTATUS:
20155 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
20156 case NT_SIGINFO:
20157 return _("NT_SIGINFO (siginfo_t data)");
20158 case NT_FILE:
20159 return _("NT_FILE (mapped files)");
20160 default:
20161 break;
20163 else
20164 switch (e_type)
20166 case NT_VERSION:
20167 return _("NT_VERSION (version)");
20168 case NT_ARCH:
20169 return _("NT_ARCH (architecture)");
20170 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
20171 return _("OPEN");
20172 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
20173 return _("func");
20174 case NT_GO_BUILDID:
20175 return _("GO BUILDID");
20176 case FDO_PACKAGING_METADATA:
20177 return _("FDO_PACKAGING_METADATA");
20178 default:
20179 break;
20182 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20183 return buff;
20186 static bool
20187 print_core_note (Elf_Internal_Note *pnote)
20189 unsigned int addr_size = is_32bit_elf ? 4 : 8;
20190 uint64_t count, page_size;
20191 unsigned char *descdata, *filenames, *descend;
20193 if (pnote->type != NT_FILE)
20195 if (do_wide)
20196 printf ("\n");
20197 return true;
20200 if (!is_32bit_elf)
20202 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
20203 /* Still "successful". */
20204 return true;
20207 if (pnote->descsz < 2 * addr_size)
20209 error (_(" Malformed note - too short for header\n"));
20210 return false;
20213 descdata = (unsigned char *) pnote->descdata;
20214 descend = descdata + pnote->descsz;
20216 if (descdata[pnote->descsz - 1] != '\0')
20218 error (_(" Malformed note - does not end with \\0\n"));
20219 return false;
20222 count = byte_get (descdata, addr_size);
20223 descdata += addr_size;
20225 page_size = byte_get (descdata, addr_size);
20226 descdata += addr_size;
20228 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
20229 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
20231 error (_(" Malformed note - too short for supplied file count\n"));
20232 return false;
20235 printf (_(" Page size: "));
20236 print_vma (page_size, DEC);
20237 printf ("\n");
20239 printf (_(" %*s%*s%*s\n"),
20240 (int) (2 + 2 * addr_size), _("Start"),
20241 (int) (4 + 2 * addr_size), _("End"),
20242 (int) (4 + 2 * addr_size), _("Page Offset"));
20243 filenames = descdata + count * 3 * addr_size;
20244 while (count-- > 0)
20246 uint64_t start, end, file_ofs;
20248 if (filenames == descend)
20250 error (_(" Malformed note - filenames end too early\n"));
20251 return false;
20254 start = byte_get (descdata, addr_size);
20255 descdata += addr_size;
20256 end = byte_get (descdata, addr_size);
20257 descdata += addr_size;
20258 file_ofs = byte_get (descdata, addr_size);
20259 descdata += addr_size;
20261 printf (" ");
20262 print_vma (start, FULL_HEX);
20263 printf (" ");
20264 print_vma (end, FULL_HEX);
20265 printf (" ");
20266 print_vma (file_ofs, FULL_HEX);
20267 printf ("\n %s\n", filenames);
20269 filenames += 1 + strlen ((char *) filenames);
20272 return true;
20275 static const char *
20276 get_gnu_elf_note_type (unsigned e_type)
20278 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
20279 switch (e_type)
20281 case NT_GNU_ABI_TAG:
20282 return _("NT_GNU_ABI_TAG (ABI version tag)");
20283 case NT_GNU_HWCAP:
20284 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
20285 case NT_GNU_BUILD_ID:
20286 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
20287 case NT_GNU_GOLD_VERSION:
20288 return _("NT_GNU_GOLD_VERSION (gold version)");
20289 case NT_GNU_PROPERTY_TYPE_0:
20290 return _("NT_GNU_PROPERTY_TYPE_0");
20291 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
20292 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
20293 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
20294 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
20295 default:
20297 static char buff[64];
20299 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20300 return buff;
20305 static void
20306 decode_x86_compat_isa (unsigned int bitmask)
20308 while (bitmask)
20310 unsigned int bit = bitmask & (- bitmask);
20312 bitmask &= ~ bit;
20313 switch (bit)
20315 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
20316 printf ("i486");
20317 break;
20318 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
20319 printf ("586");
20320 break;
20321 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
20322 printf ("686");
20323 break;
20324 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
20325 printf ("SSE");
20326 break;
20327 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
20328 printf ("SSE2");
20329 break;
20330 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
20331 printf ("SSE3");
20332 break;
20333 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
20334 printf ("SSSE3");
20335 break;
20336 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
20337 printf ("SSE4_1");
20338 break;
20339 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
20340 printf ("SSE4_2");
20341 break;
20342 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
20343 printf ("AVX");
20344 break;
20345 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
20346 printf ("AVX2");
20347 break;
20348 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
20349 printf ("AVX512F");
20350 break;
20351 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
20352 printf ("AVX512CD");
20353 break;
20354 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
20355 printf ("AVX512ER");
20356 break;
20357 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
20358 printf ("AVX512PF");
20359 break;
20360 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
20361 printf ("AVX512VL");
20362 break;
20363 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
20364 printf ("AVX512DQ");
20365 break;
20366 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
20367 printf ("AVX512BW");
20368 break;
20369 default:
20370 printf (_("<unknown: %x>"), bit);
20371 break;
20373 if (bitmask)
20374 printf (", ");
20378 static void
20379 decode_x86_compat_2_isa (unsigned int bitmask)
20381 if (!bitmask)
20383 printf (_("<None>"));
20384 return;
20387 while (bitmask)
20389 unsigned int bit = bitmask & (- bitmask);
20391 bitmask &= ~ bit;
20392 switch (bit)
20394 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
20395 printf ("CMOV");
20396 break;
20397 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
20398 printf ("SSE");
20399 break;
20400 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
20401 printf ("SSE2");
20402 break;
20403 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
20404 printf ("SSE3");
20405 break;
20406 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
20407 printf ("SSSE3");
20408 break;
20409 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
20410 printf ("SSE4_1");
20411 break;
20412 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
20413 printf ("SSE4_2");
20414 break;
20415 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
20416 printf ("AVX");
20417 break;
20418 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
20419 printf ("AVX2");
20420 break;
20421 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
20422 printf ("FMA");
20423 break;
20424 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
20425 printf ("AVX512F");
20426 break;
20427 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
20428 printf ("AVX512CD");
20429 break;
20430 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
20431 printf ("AVX512ER");
20432 break;
20433 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
20434 printf ("AVX512PF");
20435 break;
20436 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
20437 printf ("AVX512VL");
20438 break;
20439 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
20440 printf ("AVX512DQ");
20441 break;
20442 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
20443 printf ("AVX512BW");
20444 break;
20445 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
20446 printf ("AVX512_4FMAPS");
20447 break;
20448 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
20449 printf ("AVX512_4VNNIW");
20450 break;
20451 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
20452 printf ("AVX512_BITALG");
20453 break;
20454 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
20455 printf ("AVX512_IFMA");
20456 break;
20457 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
20458 printf ("AVX512_VBMI");
20459 break;
20460 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
20461 printf ("AVX512_VBMI2");
20462 break;
20463 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
20464 printf ("AVX512_VNNI");
20465 break;
20466 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
20467 printf ("AVX512_BF16");
20468 break;
20469 default:
20470 printf (_("<unknown: %x>"), bit);
20471 break;
20473 if (bitmask)
20474 printf (", ");
20478 static const char *
20479 get_amdgpu_elf_note_type (unsigned int e_type)
20481 switch (e_type)
20483 case NT_AMDGPU_METADATA:
20484 return _("NT_AMDGPU_METADATA (code object metadata)");
20485 default:
20487 static char buf[64];
20488 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
20489 return buf;
20494 static void
20495 decode_x86_isa (unsigned int bitmask)
20497 while (bitmask)
20499 unsigned int bit = bitmask & (- bitmask);
20501 bitmask &= ~ bit;
20502 switch (bit)
20504 case GNU_PROPERTY_X86_ISA_1_BASELINE:
20505 printf ("x86-64-baseline");
20506 break;
20507 case GNU_PROPERTY_X86_ISA_1_V2:
20508 printf ("x86-64-v2");
20509 break;
20510 case GNU_PROPERTY_X86_ISA_1_V3:
20511 printf ("x86-64-v3");
20512 break;
20513 case GNU_PROPERTY_X86_ISA_1_V4:
20514 printf ("x86-64-v4");
20515 break;
20516 default:
20517 printf (_("<unknown: %x>"), bit);
20518 break;
20520 if (bitmask)
20521 printf (", ");
20525 static void
20526 decode_x86_feature_1 (unsigned int bitmask)
20528 if (!bitmask)
20530 printf (_("<None>"));
20531 return;
20534 while (bitmask)
20536 unsigned int bit = bitmask & (- bitmask);
20538 bitmask &= ~ bit;
20539 switch (bit)
20541 case GNU_PROPERTY_X86_FEATURE_1_IBT:
20542 printf ("IBT");
20543 break;
20544 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
20545 printf ("SHSTK");
20546 break;
20547 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
20548 printf ("LAM_U48");
20549 break;
20550 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
20551 printf ("LAM_U57");
20552 break;
20553 default:
20554 printf (_("<unknown: %x>"), bit);
20555 break;
20557 if (bitmask)
20558 printf (", ");
20562 static void
20563 decode_x86_feature_2 (unsigned int bitmask)
20565 if (!bitmask)
20567 printf (_("<None>"));
20568 return;
20571 while (bitmask)
20573 unsigned int bit = bitmask & (- bitmask);
20575 bitmask &= ~ bit;
20576 switch (bit)
20578 case GNU_PROPERTY_X86_FEATURE_2_X86:
20579 printf ("x86");
20580 break;
20581 case GNU_PROPERTY_X86_FEATURE_2_X87:
20582 printf ("x87");
20583 break;
20584 case GNU_PROPERTY_X86_FEATURE_2_MMX:
20585 printf ("MMX");
20586 break;
20587 case GNU_PROPERTY_X86_FEATURE_2_XMM:
20588 printf ("XMM");
20589 break;
20590 case GNU_PROPERTY_X86_FEATURE_2_YMM:
20591 printf ("YMM");
20592 break;
20593 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
20594 printf ("ZMM");
20595 break;
20596 case GNU_PROPERTY_X86_FEATURE_2_TMM:
20597 printf ("TMM");
20598 break;
20599 case GNU_PROPERTY_X86_FEATURE_2_MASK:
20600 printf ("MASK");
20601 break;
20602 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
20603 printf ("FXSR");
20604 break;
20605 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
20606 printf ("XSAVE");
20607 break;
20608 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
20609 printf ("XSAVEOPT");
20610 break;
20611 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
20612 printf ("XSAVEC");
20613 break;
20614 default:
20615 printf (_("<unknown: %x>"), bit);
20616 break;
20618 if (bitmask)
20619 printf (", ");
20623 static void
20624 decode_aarch64_feature_1_and (unsigned int bitmask)
20626 while (bitmask)
20628 unsigned int bit = bitmask & (- bitmask);
20630 bitmask &= ~ bit;
20631 switch (bit)
20633 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
20634 printf ("BTI");
20635 break;
20637 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
20638 printf ("PAC");
20639 break;
20641 default:
20642 printf (_("<unknown: %x>"), bit);
20643 break;
20645 if (bitmask)
20646 printf (", ");
20650 static void
20651 decode_1_needed (unsigned int bitmask)
20653 while (bitmask)
20655 unsigned int bit = bitmask & (- bitmask);
20657 bitmask &= ~ bit;
20658 switch (bit)
20660 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
20661 printf ("indirect external access");
20662 break;
20663 default:
20664 printf (_("<unknown: %x>"), bit);
20665 break;
20667 if (bitmask)
20668 printf (", ");
20672 static void
20673 print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
20675 unsigned char * ptr = (unsigned char *) pnote->descdata;
20676 unsigned char * ptr_end = ptr + pnote->descsz;
20677 unsigned int size = is_32bit_elf ? 4 : 8;
20679 printf (_(" Properties: "));
20681 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
20683 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
20684 return;
20687 while (ptr < ptr_end)
20689 unsigned int j;
20690 unsigned int type;
20691 unsigned int datasz;
20693 if ((size_t) (ptr_end - ptr) < 8)
20695 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
20696 break;
20699 type = byte_get (ptr, 4);
20700 datasz = byte_get (ptr + 4, 4);
20702 ptr += 8;
20704 if (datasz > (size_t) (ptr_end - ptr))
20706 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
20707 type, datasz);
20708 break;
20711 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
20713 if (filedata->file_header.e_machine == EM_X86_64
20714 || filedata->file_header.e_machine == EM_IAMCU
20715 || filedata->file_header.e_machine == EM_386)
20717 unsigned int bitmask;
20719 if (datasz == 4)
20720 bitmask = byte_get (ptr, 4);
20721 else
20722 bitmask = 0;
20724 switch (type)
20726 case GNU_PROPERTY_X86_ISA_1_USED:
20727 if (datasz != 4)
20728 printf (_("x86 ISA used: <corrupt length: %#x> "),
20729 datasz);
20730 else
20732 printf ("x86 ISA used: ");
20733 decode_x86_isa (bitmask);
20735 goto next;
20737 case GNU_PROPERTY_X86_ISA_1_NEEDED:
20738 if (datasz != 4)
20739 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20740 datasz);
20741 else
20743 printf ("x86 ISA needed: ");
20744 decode_x86_isa (bitmask);
20746 goto next;
20748 case GNU_PROPERTY_X86_FEATURE_1_AND:
20749 if (datasz != 4)
20750 printf (_("x86 feature: <corrupt length: %#x> "),
20751 datasz);
20752 else
20754 printf ("x86 feature: ");
20755 decode_x86_feature_1 (bitmask);
20757 goto next;
20759 case GNU_PROPERTY_X86_FEATURE_2_USED:
20760 if (datasz != 4)
20761 printf (_("x86 feature used: <corrupt length: %#x> "),
20762 datasz);
20763 else
20765 printf ("x86 feature used: ");
20766 decode_x86_feature_2 (bitmask);
20768 goto next;
20770 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
20771 if (datasz != 4)
20772 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
20773 else
20775 printf ("x86 feature needed: ");
20776 decode_x86_feature_2 (bitmask);
20778 goto next;
20780 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
20781 if (datasz != 4)
20782 printf (_("x86 ISA used: <corrupt length: %#x> "),
20783 datasz);
20784 else
20786 printf ("x86 ISA used: ");
20787 decode_x86_compat_isa (bitmask);
20789 goto next;
20791 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
20792 if (datasz != 4)
20793 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20794 datasz);
20795 else
20797 printf ("x86 ISA needed: ");
20798 decode_x86_compat_isa (bitmask);
20800 goto next;
20802 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
20803 if (datasz != 4)
20804 printf (_("x86 ISA used: <corrupt length: %#x> "),
20805 datasz);
20806 else
20808 printf ("x86 ISA used: ");
20809 decode_x86_compat_2_isa (bitmask);
20811 goto next;
20813 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
20814 if (datasz != 4)
20815 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20816 datasz);
20817 else
20819 printf ("x86 ISA needed: ");
20820 decode_x86_compat_2_isa (bitmask);
20822 goto next;
20824 default:
20825 break;
20828 else if (filedata->file_header.e_machine == EM_AARCH64)
20830 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
20832 printf ("AArch64 feature: ");
20833 if (datasz != 4)
20834 printf (_("<corrupt length: %#x> "), datasz);
20835 else
20836 decode_aarch64_feature_1_and (byte_get (ptr, 4));
20837 goto next;
20841 else
20843 switch (type)
20845 case GNU_PROPERTY_STACK_SIZE:
20846 printf (_("stack size: "));
20847 if (datasz != size)
20848 printf (_("<corrupt length: %#x> "), datasz);
20849 else
20850 printf ("%#" PRIx64, byte_get (ptr, size));
20851 goto next;
20853 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
20854 printf ("no copy on protected ");
20855 if (datasz)
20856 printf (_("<corrupt length: %#x> "), datasz);
20857 goto next;
20859 default:
20860 if ((type >= GNU_PROPERTY_UINT32_AND_LO
20861 && type <= GNU_PROPERTY_UINT32_AND_HI)
20862 || (type >= GNU_PROPERTY_UINT32_OR_LO
20863 && type <= GNU_PROPERTY_UINT32_OR_HI))
20865 switch (type)
20867 case GNU_PROPERTY_1_NEEDED:
20868 if (datasz != 4)
20869 printf (_("1_needed: <corrupt length: %#x> "),
20870 datasz);
20871 else
20873 unsigned int bitmask = byte_get (ptr, 4);
20874 printf ("1_needed: ");
20875 decode_1_needed (bitmask);
20877 goto next;
20879 default:
20880 break;
20882 if (type <= GNU_PROPERTY_UINT32_AND_HI)
20883 printf (_("UINT32_AND (%#x): "), type);
20884 else
20885 printf (_("UINT32_OR (%#x): "), type);
20886 if (datasz != 4)
20887 printf (_("<corrupt length: %#x> "), datasz);
20888 else
20889 printf ("%#x", (unsigned int) byte_get (ptr, 4));
20890 goto next;
20892 break;
20896 if (type < GNU_PROPERTY_LOPROC)
20897 printf (_("<unknown type %#x data: "), type);
20898 else if (type < GNU_PROPERTY_LOUSER)
20899 printf (_("<processor-specific type %#x data: "), type);
20900 else
20901 printf (_("<application-specific type %#x data: "), type);
20902 for (j = 0; j < datasz; ++j)
20903 printf ("%02x ", ptr[j] & 0xff);
20904 printf (">");
20906 next:
20907 ptr += ((datasz + (size - 1)) & ~ (size - 1));
20908 if (ptr == ptr_end)
20909 break;
20911 if (do_wide)
20912 printf (", ");
20913 else
20914 printf ("\n\t");
20917 printf ("\n");
20920 static bool
20921 print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
20923 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
20924 switch (pnote->type)
20926 case NT_GNU_BUILD_ID:
20928 size_t i;
20930 printf (_(" Build ID: "));
20931 for (i = 0; i < pnote->descsz; ++i)
20932 printf ("%02x", pnote->descdata[i] & 0xff);
20933 printf ("\n");
20935 break;
20937 case NT_GNU_ABI_TAG:
20939 unsigned int os, major, minor, subminor;
20940 const char *osname;
20942 /* PR 17531: file: 030-599401-0.004. */
20943 if (pnote->descsz < 16)
20945 printf (_(" <corrupt GNU_ABI_TAG>\n"));
20946 break;
20949 os = byte_get ((unsigned char *) pnote->descdata, 4);
20950 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20951 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
20952 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20954 switch (os)
20956 case GNU_ABI_TAG_LINUX:
20957 osname = "Linux";
20958 break;
20959 case GNU_ABI_TAG_HURD:
20960 osname = "Hurd";
20961 break;
20962 case GNU_ABI_TAG_SOLARIS:
20963 osname = "Solaris";
20964 break;
20965 case GNU_ABI_TAG_FREEBSD:
20966 osname = "FreeBSD";
20967 break;
20968 case GNU_ABI_TAG_NETBSD:
20969 osname = "NetBSD";
20970 break;
20971 case GNU_ABI_TAG_SYLLABLE:
20972 osname = "Syllable";
20973 break;
20974 case GNU_ABI_TAG_NACL:
20975 osname = "NaCl";
20976 break;
20977 default:
20978 osname = "Unknown";
20979 break;
20982 printf (_(" OS: %s, ABI: %d.%d.%d\n"), osname,
20983 major, minor, subminor);
20985 break;
20987 case NT_GNU_GOLD_VERSION:
20989 size_t i;
20991 printf (_(" Version: "));
20992 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20993 printf ("%c", pnote->descdata[i]);
20994 printf ("\n");
20996 break;
20998 case NT_GNU_HWCAP:
21000 unsigned int num_entries, mask;
21002 /* Hardware capabilities information. Word 0 is the number of entries.
21003 Word 1 is a bitmask of enabled entries. The rest of the descriptor
21004 is a series of entries, where each entry is a single byte followed
21005 by a nul terminated string. The byte gives the bit number to test
21006 if enabled in the bitmask. */
21007 printf (_(" Hardware Capabilities: "));
21008 if (pnote->descsz < 8)
21010 error (_("<corrupt GNU_HWCAP>\n"));
21011 return false;
21013 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
21014 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
21015 printf (_("num entries: %d, enabled mask: %x\n"), num_entries, mask);
21016 /* FIXME: Add code to display the entries... */
21018 break;
21020 case NT_GNU_PROPERTY_TYPE_0:
21021 print_gnu_property_note (filedata, pnote);
21022 break;
21024 default:
21025 /* Handle unrecognised types. An error message should have already been
21026 created by get_gnu_elf_note_type(), so all that we need to do is to
21027 display the data. */
21029 size_t i;
21031 printf (_(" Description data: "));
21032 for (i = 0; i < pnote->descsz; ++i)
21033 printf ("%02x ", pnote->descdata[i] & 0xff);
21034 printf ("\n");
21036 break;
21039 return true;
21042 static const char *
21043 get_v850_elf_note_type (enum v850_notes n_type)
21045 static char buff[64];
21047 switch (n_type)
21049 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
21050 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
21051 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
21052 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
21053 case V850_NOTE_CACHE_INFO: return _("Use of cache");
21054 case V850_NOTE_MMU_INFO: return _("Use of MMU");
21055 default:
21056 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
21057 return buff;
21061 static bool
21062 print_v850_note (Elf_Internal_Note * pnote)
21064 unsigned int val;
21066 if (pnote->descsz != 4)
21067 return false;
21069 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
21071 if (val == 0)
21073 printf (_("not set\n"));
21074 return true;
21077 switch (pnote->type)
21079 case V850_NOTE_ALIGNMENT:
21080 switch (val)
21082 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
21083 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
21085 break;
21087 case V850_NOTE_DATA_SIZE:
21088 switch (val)
21090 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
21091 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
21093 break;
21095 case V850_NOTE_FPU_INFO:
21096 switch (val)
21098 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
21099 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
21101 break;
21103 case V850_NOTE_MMU_INFO:
21104 case V850_NOTE_CACHE_INFO:
21105 case V850_NOTE_SIMD_INFO:
21106 if (val == EF_RH850_SIMD)
21108 printf (_("yes\n"));
21109 return true;
21111 break;
21113 default:
21114 /* An 'unknown note type' message will already have been displayed. */
21115 break;
21118 printf (_("unknown value: %x\n"), val);
21119 return false;
21122 static bool
21123 process_netbsd_elf_note (Elf_Internal_Note * pnote)
21125 unsigned int version;
21127 switch (pnote->type)
21129 case NT_NETBSD_IDENT:
21130 if (pnote->descsz < 1)
21131 break;
21132 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21133 if ((version / 10000) % 100)
21134 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
21135 version, version / 100000000, (version / 1000000) % 100,
21136 (version / 10000) % 100 > 26 ? "Z" : "",
21137 'A' + (version / 10000) % 26);
21138 else
21139 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
21140 version, version / 100000000, (version / 1000000) % 100,
21141 (version / 100) % 100);
21142 return true;
21144 case NT_NETBSD_MARCH:
21145 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
21146 pnote->descdata);
21147 return true;
21149 case NT_NETBSD_PAX:
21150 if (pnote->descsz < 1)
21151 break;
21152 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21153 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
21154 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
21155 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
21156 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
21157 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
21158 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
21159 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
21160 return true;
21163 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
21164 pnote->descsz, pnote->type);
21165 return false;
21168 static const char *
21169 get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
21171 switch (e_type)
21173 case NT_FREEBSD_THRMISC:
21174 return _("NT_THRMISC (thrmisc structure)");
21175 case NT_FREEBSD_PROCSTAT_PROC:
21176 return _("NT_PROCSTAT_PROC (proc data)");
21177 case NT_FREEBSD_PROCSTAT_FILES:
21178 return _("NT_PROCSTAT_FILES (files data)");
21179 case NT_FREEBSD_PROCSTAT_VMMAP:
21180 return _("NT_PROCSTAT_VMMAP (vmmap data)");
21181 case NT_FREEBSD_PROCSTAT_GROUPS:
21182 return _("NT_PROCSTAT_GROUPS (groups data)");
21183 case NT_FREEBSD_PROCSTAT_UMASK:
21184 return _("NT_PROCSTAT_UMASK (umask data)");
21185 case NT_FREEBSD_PROCSTAT_RLIMIT:
21186 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
21187 case NT_FREEBSD_PROCSTAT_OSREL:
21188 return _("NT_PROCSTAT_OSREL (osreldate data)");
21189 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
21190 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
21191 case NT_FREEBSD_PROCSTAT_AUXV:
21192 return _("NT_PROCSTAT_AUXV (auxv data)");
21193 case NT_FREEBSD_PTLWPINFO:
21194 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
21195 case NT_FREEBSD_X86_SEGBASES:
21196 return _("NT_X86_SEGBASES (x86 segment base registers)");
21198 return get_note_type (filedata, e_type);
21201 static const char *
21202 get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
21204 static char buff[64];
21206 switch (e_type)
21208 case NT_NETBSDCORE_PROCINFO:
21209 /* NetBSD core "procinfo" structure. */
21210 return _("NetBSD procinfo structure");
21212 case NT_NETBSDCORE_AUXV:
21213 return _("NetBSD ELF auxiliary vector data");
21215 case NT_NETBSDCORE_LWPSTATUS:
21216 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
21218 default:
21219 /* As of Jan 2020 there are no other machine-independent notes
21220 defined for NetBSD core files. If the note type is less
21221 than the start of the machine-dependent note types, we don't
21222 understand it. */
21224 if (e_type < NT_NETBSDCORE_FIRSTMACH)
21226 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21227 return buff;
21229 break;
21232 switch (filedata->file_header.e_machine)
21234 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
21235 and PT_GETFPREGS == mach+2. */
21237 case EM_OLD_ALPHA:
21238 case EM_ALPHA:
21239 case EM_SPARC:
21240 case EM_SPARC32PLUS:
21241 case EM_SPARCV9:
21242 switch (e_type)
21244 case NT_NETBSDCORE_FIRSTMACH + 0:
21245 return _("PT_GETREGS (reg structure)");
21246 case NT_NETBSDCORE_FIRSTMACH + 2:
21247 return _("PT_GETFPREGS (fpreg structure)");
21248 default:
21249 break;
21251 break;
21253 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
21254 There's also old PT___GETREGS40 == mach + 1 for old reg
21255 structure which lacks GBR. */
21256 case EM_SH:
21257 switch (e_type)
21259 case NT_NETBSDCORE_FIRSTMACH + 1:
21260 return _("PT___GETREGS40 (old reg structure)");
21261 case NT_NETBSDCORE_FIRSTMACH + 3:
21262 return _("PT_GETREGS (reg structure)");
21263 case NT_NETBSDCORE_FIRSTMACH + 5:
21264 return _("PT_GETFPREGS (fpreg structure)");
21265 default:
21266 break;
21268 break;
21270 /* On all other arch's, PT_GETREGS == mach+1 and
21271 PT_GETFPREGS == mach+3. */
21272 default:
21273 switch (e_type)
21275 case NT_NETBSDCORE_FIRSTMACH + 1:
21276 return _("PT_GETREGS (reg structure)");
21277 case NT_NETBSDCORE_FIRSTMACH + 3:
21278 return _("PT_GETFPREGS (fpreg structure)");
21279 default:
21280 break;
21284 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
21285 e_type - NT_NETBSDCORE_FIRSTMACH);
21286 return buff;
21289 static const char *
21290 get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
21292 switch (e_type)
21294 case NT_OPENBSD_PROCINFO:
21295 return _("OpenBSD procinfo structure");
21296 case NT_OPENBSD_AUXV:
21297 return _("OpenBSD ELF auxiliary vector data");
21298 case NT_OPENBSD_REGS:
21299 return _("OpenBSD regular registers");
21300 case NT_OPENBSD_FPREGS:
21301 return _("OpenBSD floating point registers");
21302 case NT_OPENBSD_WCOOKIE:
21303 return _("OpenBSD window cookie");
21306 return get_note_type (filedata, e_type);
21309 static const char *
21310 get_qnx_elfcore_note_type (Filedata * filedata, unsigned e_type)
21312 switch (e_type)
21314 case QNT_DEBUG_FULLPATH:
21315 return _("QNX debug fullpath");
21316 case QNT_DEBUG_RELOC:
21317 return _("QNX debug relocation");
21318 case QNT_STACK:
21319 return _("QNX stack");
21320 case QNT_GENERATOR:
21321 return _("QNX generator");
21322 case QNT_DEFAULT_LIB:
21323 return _("QNX default library");
21324 case QNT_CORE_SYSINFO:
21325 return _("QNX core sysinfo");
21326 case QNT_CORE_INFO:
21327 return _("QNX core info");
21328 case QNT_CORE_STATUS:
21329 return _("QNX core status");
21330 case QNT_CORE_GREG:
21331 return _("QNX general registers");
21332 case QNT_CORE_FPREG:
21333 return _("QNX floating point registers");
21334 case QNT_LINK_MAP:
21335 return _("QNX link map");
21338 return get_note_type (filedata, e_type);
21341 static const char *
21342 get_stapsdt_note_type (unsigned e_type)
21344 static char buff[64];
21346 switch (e_type)
21348 case NT_STAPSDT:
21349 return _("NT_STAPSDT (SystemTap probe descriptors)");
21351 default:
21352 break;
21355 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21356 return buff;
21359 static bool
21360 print_stapsdt_note (Elf_Internal_Note *pnote)
21362 size_t len, maxlen;
21363 size_t addr_size = is_32bit_elf ? 4 : 8;
21364 char *data = pnote->descdata;
21365 char *data_end = pnote->descdata + pnote->descsz;
21366 uint64_t pc, base_addr, semaphore;
21367 char *provider, *probe, *arg_fmt;
21369 if (pnote->descsz < (addr_size * 3))
21370 goto stapdt_note_too_small;
21372 pc = byte_get ((unsigned char *) data, addr_size);
21373 data += addr_size;
21375 base_addr = byte_get ((unsigned char *) data, addr_size);
21376 data += addr_size;
21378 semaphore = byte_get ((unsigned char *) data, addr_size);
21379 data += addr_size;
21381 if (data >= data_end)
21382 goto stapdt_note_too_small;
21383 maxlen = data_end - data;
21384 len = strnlen (data, maxlen);
21385 if (len < maxlen)
21387 provider = data;
21388 data += len + 1;
21390 else
21391 goto stapdt_note_too_small;
21393 if (data >= data_end)
21394 goto stapdt_note_too_small;
21395 maxlen = data_end - data;
21396 len = strnlen (data, maxlen);
21397 if (len < maxlen)
21399 probe = data;
21400 data += len + 1;
21402 else
21403 goto stapdt_note_too_small;
21405 if (data >= data_end)
21406 goto stapdt_note_too_small;
21407 maxlen = data_end - data;
21408 len = strnlen (data, maxlen);
21409 if (len < maxlen)
21411 arg_fmt = data;
21412 data += len + 1;
21414 else
21415 goto stapdt_note_too_small;
21417 printf (_(" Provider: %s\n"), provider);
21418 printf (_(" Name: %s\n"), probe);
21419 printf (_(" Location: "));
21420 print_vma (pc, FULL_HEX);
21421 printf (_(", Base: "));
21422 print_vma (base_addr, FULL_HEX);
21423 printf (_(", Semaphore: "));
21424 print_vma (semaphore, FULL_HEX);
21425 printf ("\n");
21426 printf (_(" Arguments: %s\n"), arg_fmt);
21428 return data == data_end;
21430 stapdt_note_too_small:
21431 printf (_(" <corrupt - note is too small>\n"));
21432 error (_("corrupt stapdt note - the data size is too small\n"));
21433 return false;
21436 static bool
21437 print_fdo_note (Elf_Internal_Note * pnote)
21439 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
21441 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
21442 return true;
21444 return false;
21447 static const char *
21448 get_ia64_vms_note_type (unsigned e_type)
21450 static char buff[64];
21452 switch (e_type)
21454 case NT_VMS_MHD:
21455 return _("NT_VMS_MHD (module header)");
21456 case NT_VMS_LNM:
21457 return _("NT_VMS_LNM (language name)");
21458 case NT_VMS_SRC:
21459 return _("NT_VMS_SRC (source files)");
21460 case NT_VMS_TITLE:
21461 return "NT_VMS_TITLE";
21462 case NT_VMS_EIDC:
21463 return _("NT_VMS_EIDC (consistency check)");
21464 case NT_VMS_FPMODE:
21465 return _("NT_VMS_FPMODE (FP mode)");
21466 case NT_VMS_LINKTIME:
21467 return "NT_VMS_LINKTIME";
21468 case NT_VMS_IMGNAM:
21469 return _("NT_VMS_IMGNAM (image name)");
21470 case NT_VMS_IMGID:
21471 return _("NT_VMS_IMGID (image id)");
21472 case NT_VMS_LINKID:
21473 return _("NT_VMS_LINKID (link id)");
21474 case NT_VMS_IMGBID:
21475 return _("NT_VMS_IMGBID (build id)");
21476 case NT_VMS_GSTNAM:
21477 return _("NT_VMS_GSTNAM (sym table name)");
21478 case NT_VMS_ORIG_DYN:
21479 return "NT_VMS_ORIG_DYN";
21480 case NT_VMS_PATCHTIME:
21481 return "NT_VMS_PATCHTIME";
21482 default:
21483 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21484 return buff;
21488 static bool
21489 print_ia64_vms_note (Elf_Internal_Note * pnote)
21491 unsigned int maxlen = pnote->descsz;
21493 if (maxlen < 2 || maxlen != pnote->descsz)
21494 goto desc_size_fail;
21496 switch (pnote->type)
21498 case NT_VMS_MHD:
21499 if (maxlen <= 36)
21500 goto desc_size_fail;
21502 size_t l = strnlen (pnote->descdata + 34, maxlen - 34);
21504 printf (_(" Creation date : %.17s\n"), pnote->descdata);
21505 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
21506 if (l + 34 < maxlen)
21508 printf (_(" Module name : %s\n"), pnote->descdata + 34);
21509 if (l + 35 < maxlen)
21510 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
21511 else
21512 printf (_(" Module version : <missing>\n"));
21514 else
21516 printf (_(" Module name : <missing>\n"));
21517 printf (_(" Module version : <missing>\n"));
21519 break;
21521 case NT_VMS_LNM:
21522 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
21523 break;
21525 case NT_VMS_FPMODE:
21526 printf (_(" Floating Point mode: "));
21527 if (maxlen < 8)
21528 goto desc_size_fail;
21529 /* FIXME: Generate an error if descsz > 8 ? */
21531 printf ("0x%016" PRIx64 "\n",
21532 byte_get ((unsigned char *) pnote->descdata, 8));
21533 break;
21535 case NT_VMS_LINKTIME:
21536 printf (_(" Link time: "));
21537 if (maxlen < 8)
21538 goto desc_size_fail;
21539 /* FIXME: Generate an error if descsz > 8 ? */
21541 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
21542 printf ("\n");
21543 break;
21545 case NT_VMS_PATCHTIME:
21546 printf (_(" Patch time: "));
21547 if (maxlen < 8)
21548 goto desc_size_fail;
21549 /* FIXME: Generate an error if descsz > 8 ? */
21551 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
21552 printf ("\n");
21553 break;
21555 case NT_VMS_ORIG_DYN:
21556 if (maxlen < 34)
21557 goto desc_size_fail;
21559 printf (_(" Major id: %u, minor id: %u\n"),
21560 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
21561 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
21562 printf (_(" Last modified : "));
21563 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
21564 printf (_("\n Link flags : "));
21565 printf ("0x%016" PRIx64 "\n",
21566 byte_get ((unsigned char *) pnote->descdata + 16, 8));
21567 printf (_(" Header flags: 0x%08x\n"),
21568 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
21569 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
21570 break;
21572 case NT_VMS_IMGNAM:
21573 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
21574 break;
21576 case NT_VMS_GSTNAM:
21577 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
21578 break;
21580 case NT_VMS_IMGID:
21581 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
21582 break;
21584 case NT_VMS_LINKID:
21585 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
21586 break;
21588 default:
21589 return false;
21592 return true;
21594 desc_size_fail:
21595 printf (_(" <corrupt - data size is too small>\n"));
21596 error (_("corrupt IA64 note: data size is too small\n"));
21597 return false;
21600 struct build_attr_cache {
21601 Filedata *filedata;
21602 char *strtab;
21603 uint64_t strtablen;
21604 Elf_Internal_Sym *symtab;
21605 uint64_t nsyms;
21606 } ba_cache;
21608 /* Find the symbol associated with a build attribute that is attached
21609 to address OFFSET. If PNAME is non-NULL then store the name of
21610 the symbol (if found) in the provided pointer, Returns NULL if a
21611 symbol could not be found. */
21613 static Elf_Internal_Sym *
21614 get_symbol_for_build_attribute (Filedata *filedata,
21615 uint64_t offset,
21616 bool is_open_attr,
21617 const char **pname)
21619 Elf_Internal_Sym *saved_sym = NULL;
21620 Elf_Internal_Sym *sym;
21622 if (filedata->section_headers != NULL
21623 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
21625 Elf_Internal_Shdr * symsec;
21627 free (ba_cache.strtab);
21628 ba_cache.strtab = NULL;
21629 free (ba_cache.symtab);
21630 ba_cache.symtab = NULL;
21632 /* Load the symbol and string sections. */
21633 for (symsec = filedata->section_headers;
21634 symsec < filedata->section_headers + filedata->file_header.e_shnum;
21635 symsec ++)
21637 if (symsec->sh_type == SHT_SYMTAB
21638 && get_symtab (filedata, symsec,
21639 &ba_cache.symtab, &ba_cache.nsyms,
21640 &ba_cache.strtab, &ba_cache.strtablen))
21641 break;
21643 ba_cache.filedata = filedata;
21646 if (ba_cache.symtab == NULL)
21647 return NULL;
21649 /* Find a symbol whose value matches offset. */
21650 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
21651 if (sym->st_value == offset)
21653 if (sym->st_name >= ba_cache.strtablen)
21654 /* Huh ? This should not happen. */
21655 continue;
21657 if (ba_cache.strtab[sym->st_name] == 0)
21658 continue;
21660 /* The AArch64, ARM and RISC-V architectures define mapping symbols
21661 (eg $d, $x, $t) which we want to ignore. */
21662 if (ba_cache.strtab[sym->st_name] == '$'
21663 && ba_cache.strtab[sym->st_name + 1] != 0
21664 && ba_cache.strtab[sym->st_name + 2] == 0)
21665 continue;
21667 if (is_open_attr)
21669 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
21670 and FILE or OBJECT symbols over NOTYPE symbols. We skip
21671 FUNC symbols entirely. */
21672 switch (ELF_ST_TYPE (sym->st_info))
21674 case STT_OBJECT:
21675 case STT_FILE:
21676 saved_sym = sym;
21677 if (sym->st_size)
21679 /* If the symbol has a size associated
21680 with it then we can stop searching. */
21681 sym = ba_cache.symtab + ba_cache.nsyms;
21683 continue;
21685 case STT_FUNC:
21686 /* Ignore function symbols. */
21687 continue;
21689 default:
21690 break;
21693 switch (ELF_ST_BIND (sym->st_info))
21695 case STB_GLOBAL:
21696 if (saved_sym == NULL
21697 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
21698 saved_sym = sym;
21699 break;
21701 case STB_LOCAL:
21702 if (saved_sym == NULL)
21703 saved_sym = sym;
21704 break;
21706 default:
21707 break;
21710 else
21712 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
21713 continue;
21715 saved_sym = sym;
21716 break;
21720 if (saved_sym && pname)
21721 * pname = ba_cache.strtab + saved_sym->st_name;
21723 return saved_sym;
21726 /* Returns true iff addr1 and addr2 are in the same section. */
21728 static bool
21729 same_section (Filedata * filedata, uint64_t addr1, uint64_t addr2)
21731 Elf_Internal_Shdr * a1;
21732 Elf_Internal_Shdr * a2;
21734 a1 = find_section_by_address (filedata, addr1);
21735 a2 = find_section_by_address (filedata, addr2);
21737 return a1 == a2 && a1 != NULL;
21740 static bool
21741 print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
21742 Filedata * filedata)
21744 static uint64_t global_offset = 0;
21745 static uint64_t global_end = 0;
21746 static uint64_t func_offset = 0;
21747 static uint64_t func_end = 0;
21749 Elf_Internal_Sym *sym;
21750 const char *name;
21751 uint64_t start;
21752 uint64_t end;
21753 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
21755 switch (pnote->descsz)
21757 case 0:
21758 /* A zero-length description means that the range of
21759 the previous note of the same type should be used. */
21760 if (is_open_attr)
21762 if (global_end > global_offset)
21763 printf (_(" Applies to region from %#" PRIx64
21764 " to %#" PRIx64 "\n"), global_offset, global_end);
21765 else
21766 printf (_(" Applies to region from %#" PRIx64
21767 "\n"), global_offset);
21769 else
21771 if (func_end > func_offset)
21772 printf (_(" Applies to region from %#" PRIx64
21773 " to %#" PRIx64 "\n"), func_offset, func_end);
21774 else
21775 printf (_(" Applies to region from %#" PRIx64
21776 "\n"), func_offset);
21778 return true;
21780 case 4:
21781 start = byte_get ((unsigned char *) pnote->descdata, 4);
21782 end = 0;
21783 break;
21785 case 8:
21786 start = byte_get ((unsigned char *) pnote->descdata, 4);
21787 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
21788 break;
21790 case 16:
21791 start = byte_get ((unsigned char *) pnote->descdata, 8);
21792 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
21793 break;
21795 default:
21796 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
21797 printf (_(" <invalid descsz>"));
21798 return false;
21801 name = NULL;
21802 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
21803 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
21804 in order to avoid them being confused with the start address of the
21805 first function in the file... */
21806 if (sym == NULL && is_open_attr)
21807 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
21808 & name);
21810 if (end == 0 && sym != NULL && sym->st_size > 0)
21811 end = start + sym->st_size;
21813 if (is_open_attr)
21815 /* FIXME: Need to properly allow for section alignment.
21816 16 is just the alignment used on x86_64. */
21817 if (global_end > 0
21818 && start > BFD_ALIGN (global_end, 16)
21819 /* Build notes are not guaranteed to be organised in order of
21820 increasing address, but we should find the all of the notes
21821 for one section in the same place. */
21822 && same_section (filedata, start, global_end))
21823 warn (_("Gap in build notes detected from %#" PRIx64
21824 " to %#" PRIx64 "\n"),
21825 global_end + 1, start - 1);
21827 printf (_(" Applies to region from %#" PRIx64), start);
21828 global_offset = start;
21830 if (end)
21832 printf (_(" to %#" PRIx64), end);
21833 global_end = end;
21836 else
21838 printf (_(" Applies to region from %#" PRIx64), start);
21839 func_offset = start;
21841 if (end)
21843 printf (_(" to %#" PRIx64), end);
21844 func_end = end;
21848 if (sym && name)
21849 printf (_(" (%s)"), name);
21851 printf ("\n");
21852 return true;
21855 static bool
21856 print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
21858 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
21859 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
21860 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
21861 char name_type;
21862 char name_attribute;
21863 const char * expected_types;
21864 const char * name = pnote->namedata;
21865 const char * text;
21866 signed int left;
21868 if (name == NULL || pnote->namesz < 2)
21870 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
21871 print_symbol_name (-20, _(" <corrupt name>"));
21872 return false;
21875 if (do_wide)
21876 left = 28;
21877 else
21878 left = 20;
21880 /* Version 2 of the spec adds a "GA" prefix to the name field. */
21881 if (name[0] == 'G' && name[1] == 'A')
21883 if (pnote->namesz < 4)
21885 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
21886 print_symbol_name (-20, _(" <corrupt name>"));
21887 return false;
21890 printf ("GA");
21891 name += 2;
21892 left -= 2;
21895 switch ((name_type = * name))
21897 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21898 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21899 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21900 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21901 printf ("%c", * name);
21902 left --;
21903 break;
21904 default:
21905 error (_("unrecognised attribute type in name field: %d\n"), name_type);
21906 print_symbol_name (-20, _("<unknown name type>"));
21907 return false;
21910 ++ name;
21911 text = NULL;
21913 switch ((name_attribute = * name))
21915 case GNU_BUILD_ATTRIBUTE_VERSION:
21916 text = _("<version>");
21917 expected_types = string_expected;
21918 ++ name;
21919 break;
21920 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21921 text = _("<stack prot>");
21922 expected_types = "!+*";
21923 ++ name;
21924 break;
21925 case GNU_BUILD_ATTRIBUTE_RELRO:
21926 text = _("<relro>");
21927 expected_types = bool_expected;
21928 ++ name;
21929 break;
21930 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
21931 text = _("<stack size>");
21932 expected_types = number_expected;
21933 ++ name;
21934 break;
21935 case GNU_BUILD_ATTRIBUTE_TOOL:
21936 text = _("<tool>");
21937 expected_types = string_expected;
21938 ++ name;
21939 break;
21940 case GNU_BUILD_ATTRIBUTE_ABI:
21941 text = _("<ABI>");
21942 expected_types = "$*";
21943 ++ name;
21944 break;
21945 case GNU_BUILD_ATTRIBUTE_PIC:
21946 text = _("<PIC>");
21947 expected_types = number_expected;
21948 ++ name;
21949 break;
21950 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
21951 text = _("<short enum>");
21952 expected_types = bool_expected;
21953 ++ name;
21954 break;
21955 default:
21956 if (ISPRINT (* name))
21958 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
21960 if (len > left && ! do_wide)
21961 len = left;
21962 printf ("%.*s:", len, name);
21963 left -= len;
21964 name += len;
21966 else
21968 static char tmpbuf [128];
21970 error (_("unrecognised byte in name field: %d\n"), * name);
21971 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
21972 text = tmpbuf;
21973 name ++;
21975 expected_types = "*$!+";
21976 break;
21979 if (text)
21980 left -= printf ("%s", text);
21982 if (strchr (expected_types, name_type) == NULL)
21983 warn (_("attribute does not have an expected type (%c)\n"), name_type);
21985 if ((size_t) (name - pnote->namedata) > pnote->namesz)
21987 error (_("corrupt name field: namesz: %lu but parsing gets to %td\n"),
21988 pnote->namesz,
21989 name - pnote->namedata);
21990 return false;
21993 if (left < 1 && ! do_wide)
21994 return true;
21996 switch (name_type)
21998 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
22000 unsigned int bytes;
22001 uint64_t val = 0;
22002 unsigned int shift = 0;
22003 char *decoded = NULL;
22005 bytes = pnote->namesz - (name - pnote->namedata);
22006 if (bytes > 0)
22007 /* The -1 is because the name field is always 0 terminated, and we
22008 want to be able to ensure that the shift in the while loop below
22009 will not overflow. */
22010 -- bytes;
22012 if (bytes > sizeof (val))
22014 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
22015 bytes);
22016 bytes = sizeof (val);
22018 /* We do not bother to warn if bytes == 0 as this can
22019 happen with some early versions of the gcc plugin. */
22021 while (bytes --)
22023 uint64_t byte = *name++ & 0xff;
22025 val |= byte << shift;
22026 shift += 8;
22029 switch (name_attribute)
22031 case GNU_BUILD_ATTRIBUTE_PIC:
22032 switch (val)
22034 case 0: decoded = "static"; break;
22035 case 1: decoded = "pic"; break;
22036 case 2: decoded = "PIC"; break;
22037 case 3: decoded = "pie"; break;
22038 case 4: decoded = "PIE"; break;
22039 default: break;
22041 break;
22042 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
22043 switch (val)
22045 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
22046 case 0: decoded = "off"; break;
22047 case 1: decoded = "on"; break;
22048 case 2: decoded = "all"; break;
22049 case 3: decoded = "strong"; break;
22050 case 4: decoded = "explicit"; break;
22051 default: break;
22053 break;
22054 default:
22055 break;
22058 if (decoded != NULL)
22060 print_symbol_name (-left, decoded);
22061 left = 0;
22063 else if (val == 0)
22065 printf ("0x0");
22066 left -= 3;
22068 else
22070 if (do_wide)
22071 left -= printf ("0x%" PRIx64, val);
22072 else
22073 left -= printf ("0x%-.*" PRIx64, left, val);
22076 break;
22077 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
22078 left -= print_symbol_name (- left, name);
22079 break;
22080 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
22081 left -= print_symbol_name (- left, "true");
22082 break;
22083 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
22084 left -= print_symbol_name (- left, "false");
22085 break;
22088 if (do_wide && left > 0)
22089 printf ("%-*s", left, " ");
22091 return true;
22094 /* Print the contents of PNOTE as hex. */
22096 static void
22097 print_note_contents_hex (Elf_Internal_Note *pnote)
22099 if (pnote->descsz)
22101 size_t i;
22103 printf (_(" description data: "));
22104 for (i = 0; i < pnote->descsz; i++)
22105 printf ("%02x ", pnote->descdata[i] & 0xff);
22106 if (!do_wide)
22107 printf ("\n");
22110 if (do_wide)
22111 printf ("\n");
22114 #if defined HAVE_MSGPACK
22116 static void
22117 print_indents (int n)
22119 printf (" ");
22121 for (int i = 0; i < n; i++)
22122 printf (" ");
22125 /* Print OBJ in human-readable form. */
22127 static void
22128 dump_msgpack_obj (const msgpack_object *obj, int indent)
22130 switch (obj->type)
22132 case MSGPACK_OBJECT_NIL:
22133 printf ("(nil)");
22134 break;
22136 case MSGPACK_OBJECT_BOOLEAN:
22137 printf ("%s", obj->via.boolean ? "true" : "false");
22138 break;
22140 case MSGPACK_OBJECT_POSITIVE_INTEGER:
22141 printf ("%" PRIu64, obj->via.u64);
22142 break;
22144 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
22145 printf ("%" PRIi64, obj->via.i64);
22146 break;
22148 case MSGPACK_OBJECT_FLOAT32:
22149 case MSGPACK_OBJECT_FLOAT64:
22150 printf ("%f", obj->via.f64);
22151 break;
22153 case MSGPACK_OBJECT_STR:
22154 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
22155 break;
22157 case MSGPACK_OBJECT_ARRAY:
22159 const msgpack_object_array *array = &obj->via.array;
22161 printf ("[\n");
22162 ++indent;
22164 for (uint32_t i = 0; i < array->size; ++i)
22166 const msgpack_object *item = &array->ptr[i];
22168 print_indents (indent);
22169 dump_msgpack_obj (item, indent);
22170 printf (",\n");
22173 --indent;
22174 print_indents (indent);
22175 printf ("]");
22176 break;
22178 break;
22180 case MSGPACK_OBJECT_MAP:
22182 const msgpack_object_map *map = &obj->via.map;
22184 printf ("{\n");
22185 ++indent;
22187 for (uint32_t i = 0; i < map->size; ++i)
22189 const msgpack_object_kv *kv = &map->ptr[i];
22190 const msgpack_object *key = &kv->key;
22191 const msgpack_object *val = &kv->val;
22193 print_indents (indent);
22194 dump_msgpack_obj (key, indent);
22195 printf (": ");
22196 dump_msgpack_obj (val, indent);
22198 printf (",\n");
22201 --indent;
22202 print_indents (indent);
22203 printf ("}");
22205 break;
22208 case MSGPACK_OBJECT_BIN:
22209 printf ("(bin)");
22210 break;
22212 case MSGPACK_OBJECT_EXT:
22213 printf ("(ext)");
22214 break;
22218 static void
22219 dump_msgpack (const msgpack_unpacked *msg)
22221 print_indents (0);
22222 dump_msgpack_obj (&msg->data, 0);
22223 printf ("\n");
22226 #endif /* defined HAVE_MSGPACK */
22228 static bool
22229 print_amdgpu_note (Elf_Internal_Note *pnote)
22231 #if defined HAVE_MSGPACK
22232 /* If msgpack is available, decode and dump the note's content. */
22233 bool ret;
22234 msgpack_unpacked msg;
22235 msgpack_unpack_return msgpack_ret;
22237 assert (pnote->type == NT_AMDGPU_METADATA);
22239 msgpack_unpacked_init (&msg);
22240 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
22241 NULL);
22243 switch (msgpack_ret)
22245 case MSGPACK_UNPACK_SUCCESS:
22246 dump_msgpack (&msg);
22247 ret = true;
22248 break;
22250 default:
22251 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
22252 ret = false;
22253 break;
22256 msgpack_unpacked_destroy (&msg);
22257 return ret;
22258 #else
22259 /* msgpack is not available, dump contents as hex. */
22260 print_note_contents_hex (pnote);
22261 return true;
22262 #endif
22265 static bool
22266 print_qnx_note (Elf_Internal_Note *pnote)
22268 switch (pnote->type)
22270 case QNT_STACK:
22271 if (pnote->descsz != 12)
22272 goto desc_size_fail;
22274 printf (_(" Stack Size: 0x%" PRIx32 "\n"),
22275 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4));
22276 printf (_(" Stack allocated: %" PRIx32 "\n"),
22277 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
22278 printf (_(" Executable: %s\n"),
22279 ((unsigned) byte_get ((unsigned char *) pnote->descdata + 8, 1)) ? "no": "yes");
22280 break;
22282 default:
22283 print_note_contents_hex(pnote);
22285 return true;
22287 desc_size_fail:
22288 printf (_(" <corrupt - data size is too small>\n"));
22289 error (_("corrupt QNX note: data size is too small\n"));
22290 return false;
22294 /* Note that by the ELF standard, the name field is already null byte
22295 terminated, and namesz includes the terminating null byte.
22296 I.E. the value of namesz for the name "FSF" is 4.
22298 If the value of namesz is zero, there is no name present. */
22300 static bool
22301 process_note (Elf_Internal_Note * pnote,
22302 Filedata * filedata)
22304 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
22305 const char * nt;
22307 if (pnote->namesz == 0)
22308 /* If there is no note name, then use the default set of
22309 note type strings. */
22310 nt = get_note_type (filedata, pnote->type);
22312 else if (startswith (pnote->namedata, "GNU"))
22313 /* GNU-specific object file notes. */
22314 nt = get_gnu_elf_note_type (pnote->type);
22316 else if (startswith (pnote->namedata, "AMDGPU"))
22317 /* AMDGPU-specific object file notes. */
22318 nt = get_amdgpu_elf_note_type (pnote->type);
22320 else if (startswith (pnote->namedata, "FreeBSD"))
22321 /* FreeBSD-specific core file notes. */
22322 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
22324 else if (startswith (pnote->namedata, "NetBSD-CORE"))
22325 /* NetBSD-specific core file notes. */
22326 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
22328 else if (startswith (pnote->namedata, "NetBSD"))
22329 /* NetBSD-specific core file notes. */
22330 return process_netbsd_elf_note (pnote);
22332 else if (startswith (pnote->namedata, "PaX"))
22333 /* NetBSD-specific core file notes. */
22334 return process_netbsd_elf_note (pnote);
22336 else if (startswith (pnote->namedata, "OpenBSD"))
22337 /* OpenBSD-specific core file notes. */
22338 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
22340 else if (startswith (pnote->namedata, "QNX"))
22341 /* QNX-specific core file notes. */
22342 nt = get_qnx_elfcore_note_type (filedata, pnote->type);
22344 else if (startswith (pnote->namedata, "SPU/"))
22346 /* SPU-specific core file notes. */
22347 nt = pnote->namedata + 4;
22348 name = "SPU";
22351 else if (startswith (pnote->namedata, "IPF/VMS"))
22352 /* VMS/ia64-specific file notes. */
22353 nt = get_ia64_vms_note_type (pnote->type);
22355 else if (startswith (pnote->namedata, "stapsdt"))
22356 nt = get_stapsdt_note_type (pnote->type);
22358 else
22359 /* Don't recognize this note name; just use the default set of
22360 note type strings. */
22361 nt = get_note_type (filedata, pnote->type);
22363 printf (" ");
22365 if (((startswith (pnote->namedata, "GA")
22366 && strchr ("*$!+", pnote->namedata[2]) != NULL)
22367 || strchr ("*$!+", pnote->namedata[0]) != NULL)
22368 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
22369 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
22370 print_gnu_build_attribute_name (pnote);
22371 else
22372 print_symbol_name (-20, name);
22374 if (do_wide)
22375 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
22376 else
22377 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
22379 if (startswith (pnote->namedata, "IPF/VMS"))
22380 return print_ia64_vms_note (pnote);
22381 else if (startswith (pnote->namedata, "GNU"))
22382 return print_gnu_note (filedata, pnote);
22383 else if (startswith (pnote->namedata, "stapsdt"))
22384 return print_stapsdt_note (pnote);
22385 else if (startswith (pnote->namedata, "CORE"))
22386 return print_core_note (pnote);
22387 else if (startswith (pnote->namedata, "FDO"))
22388 return print_fdo_note (pnote);
22389 else if (((startswith (pnote->namedata, "GA")
22390 && strchr ("*$!+", pnote->namedata[2]) != NULL)
22391 || strchr ("*$!+", pnote->namedata[0]) != NULL)
22392 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
22393 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
22394 return print_gnu_build_attribute_description (pnote, filedata);
22395 else if (startswith (pnote->namedata, "AMDGPU")
22396 && pnote->type == NT_AMDGPU_METADATA)
22397 return print_amdgpu_note (pnote);
22398 else if (startswith (pnote->namedata, "QNX"))
22399 return print_qnx_note (pnote);
22401 print_note_contents_hex (pnote);
22402 return true;
22405 static bool
22406 process_notes_at (Filedata * filedata,
22407 Elf_Internal_Shdr * section,
22408 uint64_t offset,
22409 uint64_t length,
22410 uint64_t align)
22412 Elf_External_Note *pnotes;
22413 Elf_External_Note *external;
22414 char *end;
22415 bool res = true;
22417 if (length <= 0)
22418 return false;
22420 if (section)
22422 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
22423 if (pnotes)
22425 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
22427 free (pnotes);
22428 return false;
22432 else
22433 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
22434 _("notes"));
22436 if (pnotes == NULL)
22437 return false;
22439 external = pnotes;
22441 if (filedata->is_separate)
22442 printf (_("In linked file '%s': "), filedata->file_name);
22443 else
22444 printf ("\n");
22445 if (section)
22446 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
22447 else
22448 printf (_("Displaying notes found at file offset 0x%08" PRIx64
22449 " with length 0x%08" PRIx64 ":\n"),
22450 offset, length);
22452 /* NB: Some note sections may have alignment value of 0 or 1. gABI
22453 specifies that notes should be aligned to 4 bytes in 32-bit
22454 objects and to 8 bytes in 64-bit objects. As a Linux extension,
22455 we also support 4 byte alignment in 64-bit objects. If section
22456 alignment is less than 4, we treate alignment as 4 bytes. */
22457 if (align < 4)
22458 align = 4;
22459 else if (align != 4 && align != 8)
22461 warn (_("Corrupt note: alignment %" PRId64 ", expecting 4 or 8\n"),
22462 align);
22463 free (pnotes);
22464 return false;
22467 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
22469 end = (char *) pnotes + length;
22470 while ((char *) external < end)
22472 Elf_Internal_Note inote;
22473 size_t min_notesz;
22474 char * next;
22475 char * temp = NULL;
22476 size_t data_remaining = end - (char *) external;
22478 if (!is_ia64_vms (filedata))
22480 /* PR binutils/15191
22481 Make sure that there is enough data to read. */
22482 min_notesz = offsetof (Elf_External_Note, name);
22483 if (data_remaining < min_notesz)
22485 warn (ngettext ("Corrupt note: only %zd byte remains, "
22486 "not enough for a full note\n",
22487 "Corrupt note: only %zd bytes remain, "
22488 "not enough for a full note\n",
22489 data_remaining),
22490 data_remaining);
22491 break;
22493 data_remaining -= min_notesz;
22495 inote.type = BYTE_GET (external->type);
22496 inote.namesz = BYTE_GET (external->namesz);
22497 inote.namedata = external->name;
22498 inote.descsz = BYTE_GET (external->descsz);
22499 inote.descdata = ((char *) external
22500 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
22501 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22502 next = ((char *) external
22503 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
22505 else
22507 Elf64_External_VMS_Note *vms_external;
22509 /* PR binutils/15191
22510 Make sure that there is enough data to read. */
22511 min_notesz = offsetof (Elf64_External_VMS_Note, name);
22512 if (data_remaining < min_notesz)
22514 warn (ngettext ("Corrupt note: only %zd byte remains, "
22515 "not enough for a full note\n",
22516 "Corrupt note: only %zd bytes remain, "
22517 "not enough for a full note\n",
22518 data_remaining),
22519 data_remaining);
22520 break;
22522 data_remaining -= min_notesz;
22524 vms_external = (Elf64_External_VMS_Note *) external;
22525 inote.type = BYTE_GET (vms_external->type);
22526 inote.namesz = BYTE_GET (vms_external->namesz);
22527 inote.namedata = vms_external->name;
22528 inote.descsz = BYTE_GET (vms_external->descsz);
22529 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
22530 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22531 next = inote.descdata + align_power (inote.descsz, 3);
22534 /* PR 17531: file: 3443835e. */
22535 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
22536 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
22537 || (size_t) (inote.descdata - inote.namedata) > data_remaining
22538 || (size_t) (next - inote.descdata) < inote.descsz
22539 || ((size_t) (next - inote.descdata)
22540 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
22542 warn (_("note with invalid namesz and/or descsz found at offset %#tx\n"),
22543 (char *) external - (char *) pnotes);
22544 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx, alignment: %u\n"),
22545 inote.type, inote.namesz, inote.descsz, (int) align);
22546 break;
22549 external = (Elf_External_Note *) next;
22551 /* Verify that name is null terminated. It appears that at least
22552 one version of Linux (RedHat 6.0) generates corefiles that don't
22553 comply with the ELF spec by failing to include the null byte in
22554 namesz. */
22555 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
22557 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
22559 temp = (char *) malloc (inote.namesz + 1);
22560 if (temp == NULL)
22562 error (_("Out of memory allocating space for inote name\n"));
22563 res = false;
22564 break;
22567 memcpy (temp, inote.namedata, inote.namesz);
22568 inote.namedata = temp;
22570 inote.namedata[inote.namesz] = 0;
22573 if (! process_note (& inote, filedata))
22574 res = false;
22576 free (temp);
22577 temp = NULL;
22580 free (pnotes);
22582 return res;
22585 static bool
22586 process_corefile_note_segments (Filedata * filedata)
22588 Elf_Internal_Phdr *segment;
22589 unsigned int i;
22590 bool res = true;
22592 if (! get_program_headers (filedata))
22593 return true;
22595 for (i = 0, segment = filedata->program_headers;
22596 i < filedata->file_header.e_phnum;
22597 i++, segment++)
22599 if (segment->p_type == PT_NOTE)
22600 if (! process_notes_at (filedata, NULL, segment->p_offset,
22601 segment->p_filesz, segment->p_align))
22602 res = false;
22605 return res;
22608 static bool
22609 process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
22611 Elf_External_Note * pnotes;
22612 Elf_External_Note * external;
22613 char * end;
22614 bool res = true;
22616 if (length <= 0)
22617 return false;
22619 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
22620 _("v850 notes"));
22621 if (pnotes == NULL)
22622 return false;
22624 external = pnotes;
22625 end = (char*) pnotes + length;
22627 printf (_("\nDisplaying contents of Renesas V850 notes section at offset"
22628 " %#" PRIx64 " with length %#" PRIx64 ":\n"),
22629 offset, length);
22631 while ((char *) external + sizeof (Elf_External_Note) < end)
22633 Elf_External_Note * next;
22634 Elf_Internal_Note inote;
22636 inote.type = BYTE_GET (external->type);
22637 inote.namesz = BYTE_GET (external->namesz);
22638 inote.namedata = external->name;
22639 inote.descsz = BYTE_GET (external->descsz);
22640 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
22641 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22643 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
22645 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
22646 inote.descdata = inote.namedata;
22647 inote.namesz = 0;
22650 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
22652 if ( ((char *) next > end)
22653 || ((char *) next < (char *) pnotes))
22655 warn (_("corrupt descsz found in note at offset %#tx\n"),
22656 (char *) external - (char *) pnotes);
22657 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
22658 inote.type, inote.namesz, inote.descsz);
22659 break;
22662 external = next;
22664 /* Prevent out-of-bounds indexing. */
22665 if ( inote.namedata + inote.namesz > end
22666 || inote.namedata + inote.namesz < inote.namedata)
22668 warn (_("corrupt namesz found in note at offset %#zx\n"),
22669 (char *) external - (char *) pnotes);
22670 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
22671 inote.type, inote.namesz, inote.descsz);
22672 break;
22675 printf (" %s: ", get_v850_elf_note_type (inote.type));
22677 if (! print_v850_note (& inote))
22679 res = false;
22680 printf ("<corrupt sizes: namesz: %#lx, descsz: %#lx>\n",
22681 inote.namesz, inote.descsz);
22685 free (pnotes);
22687 return res;
22690 static bool
22691 process_note_sections (Filedata * filedata)
22693 Elf_Internal_Shdr *section;
22694 size_t i;
22695 unsigned int n = 0;
22696 bool res = true;
22698 for (i = 0, section = filedata->section_headers;
22699 i < filedata->file_header.e_shnum && section != NULL;
22700 i++, section++)
22702 if (section->sh_type == SHT_NOTE)
22704 if (! process_notes_at (filedata, section, section->sh_offset,
22705 section->sh_size, section->sh_addralign))
22706 res = false;
22707 n++;
22710 if (( filedata->file_header.e_machine == EM_V800
22711 || filedata->file_header.e_machine == EM_V850
22712 || filedata->file_header.e_machine == EM_CYGNUS_V850)
22713 && section->sh_type == SHT_RENESAS_INFO)
22715 if (! process_v850_notes (filedata, section->sh_offset,
22716 section->sh_size))
22717 res = false;
22718 n++;
22722 if (n == 0)
22723 /* Try processing NOTE segments instead. */
22724 return process_corefile_note_segments (filedata);
22726 return res;
22729 static bool
22730 process_notes (Filedata * filedata)
22732 /* If we have not been asked to display the notes then do nothing. */
22733 if (! do_notes)
22734 return true;
22736 if (filedata->file_header.e_type != ET_CORE)
22737 return process_note_sections (filedata);
22739 /* No program headers means no NOTE segment. */
22740 if (filedata->file_header.e_phnum > 0)
22741 return process_corefile_note_segments (filedata);
22743 if (filedata->is_separate)
22744 printf (_("No notes found in linked file '%s'.\n"),
22745 filedata->file_name);
22746 else
22747 printf (_("No notes found file.\n"));
22749 return true;
22752 static unsigned char *
22753 display_public_gnu_attributes (unsigned char * start,
22754 const unsigned char * const end)
22756 printf (_(" Unknown GNU attribute: %s\n"), start);
22758 start += strnlen ((char *) start, end - start);
22759 display_raw_attribute (start, end);
22761 return (unsigned char *) end;
22764 static unsigned char *
22765 display_generic_attribute (unsigned char * start,
22766 unsigned int tag,
22767 const unsigned char * const end)
22769 if (tag == 0)
22770 return (unsigned char *) end;
22772 return display_tag_value (tag, start, end);
22775 static bool
22776 process_arch_specific (Filedata * filedata)
22778 if (! do_arch)
22779 return true;
22781 switch (filedata->file_header.e_machine)
22783 case EM_ARC:
22784 case EM_ARC_COMPACT:
22785 case EM_ARC_COMPACT2:
22786 case EM_ARC_COMPACT3:
22787 case EM_ARC_COMPACT3_64:
22788 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
22789 display_arc_attribute,
22790 display_generic_attribute);
22791 case EM_ARM:
22792 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
22793 display_arm_attribute,
22794 display_generic_attribute);
22796 case EM_MIPS:
22797 case EM_MIPS_RS3_LE:
22798 return process_mips_specific (filedata);
22800 case EM_MSP430:
22801 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
22802 display_msp430_attribute,
22803 display_msp430_gnu_attribute);
22805 case EM_RISCV:
22806 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
22807 display_riscv_attribute,
22808 display_generic_attribute);
22810 case EM_NDS32:
22811 return process_nds32_specific (filedata);
22813 case EM_68K:
22814 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
22815 display_m68k_gnu_attribute);
22817 case EM_PPC:
22818 case EM_PPC64:
22819 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
22820 display_power_gnu_attribute);
22822 case EM_S390:
22823 case EM_S390_OLD:
22824 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
22825 display_s390_gnu_attribute);
22827 case EM_SPARC:
22828 case EM_SPARC32PLUS:
22829 case EM_SPARCV9:
22830 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
22831 display_sparc_gnu_attribute);
22833 case EM_TI_C6000:
22834 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
22835 display_tic6x_attribute,
22836 display_generic_attribute);
22838 case EM_CSKY:
22839 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
22840 display_csky_attribute, NULL);
22842 default:
22843 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
22844 display_public_gnu_attributes,
22845 display_generic_attribute);
22849 static bool
22850 get_file_header (Filedata * filedata)
22852 /* Read in the identity array. */
22853 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
22854 return false;
22856 /* Determine how to read the rest of the header. */
22857 switch (filedata->file_header.e_ident[EI_DATA])
22859 default:
22860 case ELFDATANONE:
22861 case ELFDATA2LSB:
22862 byte_get = byte_get_little_endian;
22863 byte_put = byte_put_little_endian;
22864 break;
22865 case ELFDATA2MSB:
22866 byte_get = byte_get_big_endian;
22867 byte_put = byte_put_big_endian;
22868 break;
22871 /* For now we only support 32 bit and 64 bit ELF files. */
22872 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
22874 /* Read in the rest of the header. */
22875 if (is_32bit_elf)
22877 Elf32_External_Ehdr ehdr32;
22879 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
22880 return false;
22882 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
22883 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
22884 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
22885 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
22886 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
22887 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
22888 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
22889 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
22890 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
22891 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
22892 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
22893 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
22894 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
22896 else
22898 Elf64_External_Ehdr ehdr64;
22900 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
22901 return false;
22903 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
22904 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
22905 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
22906 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
22907 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
22908 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
22909 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
22910 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
22911 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
22912 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
22913 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
22914 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
22915 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
22918 return true;
22921 static void
22922 free_filedata (Filedata *filedata)
22924 free (filedata->program_interpreter);
22925 free (filedata->program_headers);
22926 free (filedata->section_headers);
22927 free (filedata->string_table);
22928 free (filedata->dump.dump_sects);
22929 free (filedata->dynamic_strings);
22930 free (filedata->dynamic_symbols);
22931 free (filedata->dynamic_syminfo);
22932 free (filedata->dynamic_section);
22934 while (filedata->symtab_shndx_list != NULL)
22936 elf_section_list *next = filedata->symtab_shndx_list->next;
22937 free (filedata->symtab_shndx_list);
22938 filedata->symtab_shndx_list = next;
22941 free (filedata->section_headers_groups);
22943 if (filedata->section_groups)
22945 size_t i;
22946 struct group_list * g;
22947 struct group_list * next;
22949 for (i = 0; i < filedata->group_count; i++)
22951 for (g = filedata->section_groups [i].root; g != NULL; g = next)
22953 next = g->next;
22954 free (g);
22958 free (filedata->section_groups);
22960 memset (&filedata->section_headers, 0,
22961 sizeof (Filedata) - offsetof (Filedata, section_headers));
22964 static void
22965 close_file (Filedata * filedata)
22967 if (filedata)
22969 if (filedata->handle)
22970 fclose (filedata->handle);
22971 free (filedata);
22975 void
22976 close_debug_file (void * data)
22978 free_filedata ((Filedata *) data);
22979 close_file ((Filedata *) data);
22982 static Filedata *
22983 open_file (const char * pathname, bool is_separate)
22985 struct stat statbuf;
22986 Filedata * filedata = NULL;
22988 if (stat (pathname, & statbuf) < 0
22989 || ! S_ISREG (statbuf.st_mode))
22990 goto fail;
22992 filedata = calloc (1, sizeof * filedata);
22993 if (filedata == NULL)
22994 goto fail;
22996 filedata->handle = fopen (pathname, "rb");
22997 if (filedata->handle == NULL)
22998 goto fail;
23000 filedata->file_size = statbuf.st_size;
23001 filedata->file_name = pathname;
23002 filedata->is_separate = is_separate;
23004 if (! get_file_header (filedata))
23005 goto fail;
23007 if (!get_section_headers (filedata, false))
23008 goto fail;
23010 return filedata;
23012 fail:
23013 if (filedata)
23015 if (filedata->handle)
23016 fclose (filedata->handle);
23017 free (filedata);
23019 return NULL;
23022 void *
23023 open_debug_file (const char * pathname)
23025 return open_file (pathname, true);
23028 static void
23029 initialise_dump_sects (Filedata * filedata)
23031 /* Initialise the dump_sects array from the cmdline_dump_sects array.
23032 Note we do this even if cmdline_dump_sects is empty because we
23033 must make sure that the dump_sets array is zeroed out before each
23034 object file is processed. */
23035 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
23036 memset (filedata->dump.dump_sects, 0,
23037 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
23039 if (cmdline.num_dump_sects > 0)
23041 if (filedata->dump.num_dump_sects == 0)
23042 /* A sneaky way of allocating the dump_sects array. */
23043 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
23045 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
23046 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
23047 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
23051 static bool
23052 might_need_separate_debug_info (Filedata * filedata)
23054 /* Debuginfo files do not need further separate file loading. */
23055 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
23056 return false;
23058 /* Since do_follow_links might be enabled by default, only treat it as an
23059 indication that separate files should be loaded if setting it was a
23060 deliberate user action. */
23061 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
23062 return true;
23064 if (process_links || do_syms || do_unwind
23065 || dump_any_debugging || do_dump || do_debugging)
23066 return true;
23068 return false;
23071 /* Process one ELF object file according to the command line options.
23072 This file may actually be stored in an archive. The file is
23073 positioned at the start of the ELF object. Returns TRUE if no
23074 problems were encountered, FALSE otherwise. */
23076 static bool
23077 process_object (Filedata * filedata)
23079 bool have_separate_files;
23080 unsigned int i;
23081 bool res;
23083 if (! get_file_header (filedata))
23085 error (_("%s: Failed to read file header\n"), filedata->file_name);
23086 return false;
23089 /* Initialise per file variables. */
23090 for (i = ARRAY_SIZE (filedata->version_info); i--;)
23091 filedata->version_info[i] = 0;
23093 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
23094 filedata->dynamic_info[i] = 0;
23095 filedata->dynamic_info_DT_GNU_HASH = 0;
23096 filedata->dynamic_info_DT_MIPS_XHASH = 0;
23098 /* Process the file. */
23099 if (show_name)
23100 printf (_("\nFile: %s\n"), filedata->file_name);
23102 initialise_dump_sects (filedata);
23104 /* There may be some extensions in the first section header. Don't
23105 bomb if we can't read it. */
23106 get_section_headers (filedata, true);
23108 if (! process_file_header (filedata))
23110 res = false;
23111 goto out;
23114 /* Throw away the single section header read above, so that we
23115 re-read the entire set. */
23116 free (filedata->section_headers);
23117 filedata->section_headers = NULL;
23119 if (! process_section_headers (filedata))
23121 /* Without loaded section headers we cannot process lots of things. */
23122 do_unwind = do_version = do_dump = do_arch = false;
23124 if (! do_using_dynamic)
23125 do_syms = do_dyn_syms = do_reloc = false;
23128 if (! process_section_groups (filedata))
23129 /* Without loaded section groups we cannot process unwind. */
23130 do_unwind = false;
23132 process_program_headers (filedata);
23134 res = process_dynamic_section (filedata);
23136 if (! process_relocs (filedata))
23137 res = false;
23139 if (! process_unwind (filedata))
23140 res = false;
23142 if (! process_symbol_table (filedata))
23143 res = false;
23145 if (! process_lto_symbol_tables (filedata))
23146 res = false;
23148 if (! process_syminfo (filedata))
23149 res = false;
23151 if (! process_version_sections (filedata))
23152 res = false;
23154 if (might_need_separate_debug_info (filedata))
23155 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
23156 else
23157 have_separate_files = false;
23159 if (! process_section_contents (filedata))
23160 res = false;
23162 if (have_separate_files)
23164 separate_info * d;
23166 for (d = first_separate_info; d != NULL; d = d->next)
23168 initialise_dump_sects (d->handle);
23170 if (process_links && ! process_file_header (d->handle))
23171 res = false;
23172 else if (! process_section_headers (d->handle))
23173 res = false;
23174 else if (! process_section_contents (d->handle))
23175 res = false;
23176 else if (process_links)
23178 if (! process_section_groups (d->handle))
23179 res = false;
23180 process_program_headers (d->handle);
23181 if (! process_dynamic_section (d->handle))
23182 res = false;
23183 if (! process_relocs (d->handle))
23184 res = false;
23185 if (! process_unwind (d->handle))
23186 res = false;
23187 if (! process_symbol_table (d->handle))
23188 res = false;
23189 if (! process_lto_symbol_tables (d->handle))
23190 res = false;
23191 if (! process_syminfo (d->handle))
23192 res = false;
23193 if (! process_version_sections (d->handle))
23194 res = false;
23195 if (! process_notes (d->handle))
23196 res = false;
23200 /* The file handles are closed by the call to free_debug_memory() below. */
23203 if (! process_notes (filedata))
23204 res = false;
23206 if (! process_gnu_liblist (filedata))
23207 res = false;
23209 if (! process_arch_specific (filedata))
23210 res = false;
23212 out:
23213 free_filedata (filedata);
23215 free_debug_memory ();
23217 return res;
23220 /* Process an ELF archive.
23221 On entry the file is positioned just after the ARMAG string.
23222 Returns TRUE upon success, FALSE otherwise. */
23224 static bool
23225 process_archive (Filedata * filedata, bool is_thin_archive)
23227 struct archive_info arch;
23228 struct archive_info nested_arch;
23229 size_t got;
23230 bool ret = true;
23232 show_name = true;
23234 /* The ARCH structure is used to hold information about this archive. */
23235 arch.file_name = NULL;
23236 arch.file = NULL;
23237 arch.index_array = NULL;
23238 arch.sym_table = NULL;
23239 arch.longnames = NULL;
23241 /* The NESTED_ARCH structure is used as a single-item cache of information
23242 about a nested archive (when members of a thin archive reside within
23243 another regular archive file). */
23244 nested_arch.file_name = NULL;
23245 nested_arch.file = NULL;
23246 nested_arch.index_array = NULL;
23247 nested_arch.sym_table = NULL;
23248 nested_arch.longnames = NULL;
23250 if (setup_archive (&arch, filedata->file_name, filedata->handle,
23251 filedata->file_size, is_thin_archive,
23252 do_archive_index) != 0)
23254 ret = false;
23255 goto out;
23258 if (do_archive_index)
23260 if (arch.sym_table == NULL)
23261 error (_("%s: unable to dump the index as none was found\n"),
23262 filedata->file_name);
23263 else
23265 uint64_t i, l;
23266 uint64_t current_pos;
23268 printf (_("Index of archive %s: (%" PRIu64 " entries,"
23269 " %#" PRIx64 " bytes in the symbol table)\n"),
23270 filedata->file_name, arch.index_num,
23271 arch.sym_size);
23273 current_pos = ftell (filedata->handle);
23275 for (i = l = 0; i < arch.index_num; i++)
23277 if (i == 0
23278 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
23280 char * member_name
23281 = get_archive_member_name_at (&arch, arch.index_array[i],
23282 &nested_arch);
23284 if (member_name != NULL)
23286 char * qualified_name
23287 = make_qualified_name (&arch, &nested_arch,
23288 member_name);
23290 if (qualified_name != NULL)
23292 printf (_("Contents of binary %s at offset "),
23293 qualified_name);
23294 (void) print_vma (arch.index_array[i], PREFIX_HEX);
23295 putchar ('\n');
23296 free (qualified_name);
23298 free (member_name);
23302 if (l >= arch.sym_size)
23304 error (_("%s: end of the symbol table reached "
23305 "before the end of the index\n"),
23306 filedata->file_name);
23307 ret = false;
23308 break;
23310 /* PR 17531: file: 0b6630b2. */
23311 printf ("\t%.*s\n",
23312 (int) (arch.sym_size - l), arch.sym_table + l);
23313 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
23316 if (arch.uses_64bit_indices)
23317 l = (l + 7) & ~ 7;
23318 else
23319 l += l & 1;
23321 if (l < arch.sym_size)
23323 error (ngettext ("%s: %" PRId64 " byte remains in the symbol table, "
23324 "but without corresponding entries in "
23325 "the index table\n",
23326 "%s: %" PRId64 " bytes remain in the symbol table, "
23327 "but without corresponding entries in "
23328 "the index table\n",
23329 arch.sym_size - l),
23330 filedata->file_name, arch.sym_size - l);
23331 ret = false;
23334 if (fseek64 (filedata->handle, current_pos, SEEK_SET) != 0)
23336 error (_("%s: failed to seek back to start of object files "
23337 "in the archive\n"),
23338 filedata->file_name);
23339 ret = false;
23340 goto out;
23344 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
23345 && !do_segments && !do_header && !do_dump && !do_version
23346 && !do_histogram && !do_debugging && !do_arch && !do_notes
23347 && !do_section_groups && !do_dyn_syms)
23349 ret = true; /* Archive index only. */
23350 goto out;
23354 while (1)
23356 char * name;
23357 size_t namelen;
23358 char * qualified_name;
23360 /* Read the next archive header. */
23361 if (fseek64 (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
23363 error (_("%s: failed to seek to next archive header\n"),
23364 arch.file_name);
23365 ret = false;
23366 break;
23368 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
23369 if (got != sizeof arch.arhdr)
23371 if (got == 0)
23372 break;
23373 /* PR 24049 - we cannot use filedata->file_name as this will
23374 have already been freed. */
23375 error (_("%s: failed to read archive header\n"), arch.file_name);
23377 ret = false;
23378 break;
23380 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
23382 error (_("%s: did not find a valid archive header\n"),
23383 arch.file_name);
23384 ret = false;
23385 break;
23388 arch.next_arhdr_offset += sizeof arch.arhdr;
23390 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
23392 name = get_archive_member_name (&arch, &nested_arch);
23393 if (name == NULL)
23395 error (_("%s: bad archive file name\n"), arch.file_name);
23396 ret = false;
23397 break;
23399 namelen = strlen (name);
23401 qualified_name = make_qualified_name (&arch, &nested_arch, name);
23402 if (qualified_name == NULL)
23404 error (_("%s: bad archive file name\n"), arch.file_name);
23405 free (name);
23406 ret = false;
23407 break;
23410 if (is_thin_archive && arch.nested_member_origin == 0)
23412 /* This is a proxy for an external member of a thin archive. */
23413 Filedata * member_filedata;
23414 char * member_file_name = adjust_relative_path
23415 (filedata->file_name, name, namelen);
23417 free (name);
23418 if (member_file_name == NULL)
23420 free (qualified_name);
23421 ret = false;
23422 break;
23425 member_filedata = open_file (member_file_name, false);
23426 if (member_filedata == NULL)
23428 error (_("Input file '%s' is not readable.\n"), member_file_name);
23429 free (member_file_name);
23430 free (qualified_name);
23431 ret = false;
23432 break;
23435 filedata->archive_file_offset = arch.nested_member_origin;
23436 member_filedata->file_name = qualified_name;
23438 /* The call to process_object() expects the file to be at the beginning. */
23439 rewind (member_filedata->handle);
23441 if (! process_object (member_filedata))
23442 ret = false;
23444 close_file (member_filedata);
23445 free (member_file_name);
23447 else if (is_thin_archive)
23449 Filedata thin_filedata;
23451 memset (&thin_filedata, 0, sizeof (thin_filedata));
23453 /* PR 15140: Allow for corrupt thin archives. */
23454 if (nested_arch.file == NULL)
23456 error (_("%s: contains corrupt thin archive: %s\n"),
23457 qualified_name, name);
23458 free (qualified_name);
23459 free (name);
23460 ret = false;
23461 break;
23463 free (name);
23465 /* This is a proxy for a member of a nested archive. */
23466 filedata->archive_file_offset
23467 = arch.nested_member_origin + sizeof arch.arhdr;
23469 /* The nested archive file will have been opened and setup by
23470 get_archive_member_name. */
23471 if (fseek64 (nested_arch.file, filedata->archive_file_offset,
23472 SEEK_SET) != 0)
23474 error (_("%s: failed to seek to archive member.\n"),
23475 nested_arch.file_name);
23476 free (qualified_name);
23477 ret = false;
23478 break;
23481 thin_filedata.handle = nested_arch.file;
23482 thin_filedata.file_name = qualified_name;
23484 if (! process_object (& thin_filedata))
23485 ret = false;
23487 else
23489 free (name);
23490 filedata->archive_file_offset = arch.next_arhdr_offset;
23491 filedata->file_name = qualified_name;
23492 if (! process_object (filedata))
23493 ret = false;
23494 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
23495 /* Stop looping with "negative" archive_file_size. */
23496 if (arch.next_arhdr_offset < filedata->archive_file_size)
23497 arch.next_arhdr_offset = -1ul;
23500 free (qualified_name);
23503 out:
23504 if (nested_arch.file != NULL)
23505 fclose (nested_arch.file);
23506 release_archive (&nested_arch);
23507 release_archive (&arch);
23509 return ret;
23512 static bool
23513 process_file (char * file_name)
23515 Filedata * filedata = NULL;
23516 struct stat statbuf;
23517 char armag[SARMAG];
23518 bool ret = true;
23520 if (stat (file_name, &statbuf) < 0)
23522 if (errno == ENOENT)
23523 error (_("'%s': No such file\n"), file_name);
23524 else
23525 error (_("Could not locate '%s'. System error message: %s\n"),
23526 file_name, strerror (errno));
23527 return false;
23530 if (! S_ISREG (statbuf.st_mode))
23532 error (_("'%s' is not an ordinary file\n"), file_name);
23533 return false;
23536 filedata = calloc (1, sizeof * filedata);
23537 if (filedata == NULL)
23539 error (_("Out of memory allocating file data structure\n"));
23540 return false;
23543 filedata->file_name = file_name;
23544 filedata->handle = fopen (file_name, "rb");
23545 if (filedata->handle == NULL)
23547 error (_("Input file '%s' is not readable.\n"), file_name);
23548 free (filedata);
23549 return false;
23552 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
23554 error (_("%s: Failed to read file's magic number\n"), file_name);
23555 fclose (filedata->handle);
23556 free (filedata);
23557 return false;
23560 filedata->file_size = statbuf.st_size;
23561 filedata->is_separate = false;
23563 if (memcmp (armag, ARMAG, SARMAG) == 0)
23565 if (! process_archive (filedata, false))
23566 ret = false;
23568 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
23570 if ( ! process_archive (filedata, true))
23571 ret = false;
23573 else
23575 if (do_archive_index && !check_all)
23576 error (_("File %s is not an archive so its index cannot be displayed.\n"),
23577 file_name);
23579 rewind (filedata->handle);
23580 filedata->archive_file_size = filedata->archive_file_offset = 0;
23582 if (! process_object (filedata))
23583 ret = false;
23586 fclose (filedata->handle);
23587 free (filedata->section_headers);
23588 free (filedata->program_headers);
23589 free (filedata->string_table);
23590 free (filedata->dump.dump_sects);
23591 free (filedata);
23593 free (ba_cache.strtab);
23594 ba_cache.strtab = NULL;
23595 free (ba_cache.symtab);
23596 ba_cache.symtab = NULL;
23597 ba_cache.filedata = NULL;
23599 return ret;
23602 #ifdef SUPPORT_DISASSEMBLY
23603 /* Needed by the i386 disassembler. For extra credit, someone could
23604 fix this so that we insert symbolic addresses here, esp for GOT/PLT
23605 symbols. */
23607 void
23608 print_address (unsigned int addr, FILE * outfile)
23610 fprintf (outfile,"0x%8.8x", addr);
23613 /* Needed by the i386 disassembler. */
23615 void
23616 db_task_printsym (unsigned int addr)
23618 print_address (addr, stderr);
23620 #endif
23623 main (int argc, char ** argv)
23625 int err;
23627 #ifdef HAVE_LC_MESSAGES
23628 setlocale (LC_MESSAGES, "");
23629 #endif
23630 setlocale (LC_CTYPE, "");
23631 bindtextdomain (PACKAGE, LOCALEDIR);
23632 textdomain (PACKAGE);
23634 expandargv (&argc, &argv);
23636 parse_args (& cmdline, argc, argv);
23638 if (optind < (argc - 1))
23639 /* When displaying information for more than one file,
23640 prefix the information with the file name. */
23641 show_name = true;
23642 else if (optind >= argc)
23644 /* Ensure that the warning is always displayed. */
23645 do_checks = true;
23647 warn (_("Nothing to do.\n"));
23648 usage (stderr);
23651 err = false;
23652 while (optind < argc)
23653 if (! process_file (argv[optind++]))
23654 err = true;
23656 free (cmdline.dump_sects);
23658 free (dump_ctf_symtab_name);
23659 free (dump_ctf_strtab_name);
23660 free (dump_ctf_parent_name);
23662 return err ? EXIT_FAILURE : EXIT_SUCCESS;