Use command style in cmd_show_list
[binutils-gdb.git] / binutils / readelf.c
blob70d0c533f91838351c1963d4464bca71738cb245
1 /* readelf.c -- display contents of an ELF format file
2 Copyright (C) 1998-2025 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 #ifdef SUPPORT_DISASSEMBLY
192 #define DISASS_DUMP (1 << 1) /* The -i command line switch. */
193 #endif
194 #define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
195 #define STRING_DUMP (1 << 3) /* The -p command line switch. */
196 #define RELOC_DUMP (1 << 4) /* The -R command line switch. */
197 #define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
198 #define SFRAME_DUMP (1 << 6) /* The --sframe command line switch. */
199 #define AUTO_DUMP (1 << 7) /* The -j command line switch. */
201 typedef unsigned char dump_type;
203 /* A linked list of the section names for which dumps were requested. */
204 struct dump_list_entry
206 char * name;
207 dump_type type;
208 struct dump_list_entry * next;
211 /* A dynamic array of flags indicating for which sections a dump
212 has been requested via command line switches. */
213 struct dump_data
215 dump_type * dump_sects;
216 unsigned int num_dump_sects;
219 static struct dump_data cmdline;
221 static struct dump_list_entry * dump_sects_byname;
223 char * program_name = "readelf";
225 static bool show_name = false;
226 static bool do_dynamic = false;
227 static bool do_syms = false;
228 static bool do_dyn_syms = false;
229 static bool do_lto_syms = false;
230 static bool do_reloc = false;
231 static bool do_sections = false;
232 static bool do_section_groups = false;
233 static bool do_section_details = false;
234 static bool do_segments = false;
235 static bool do_unwind = false;
236 static bool do_using_dynamic = false;
237 static bool do_header = false;
238 static bool do_dump = false;
239 static bool do_version = false;
240 static bool do_histogram = false;
241 static bool do_debugging = false;
242 static bool do_ctf = false;
243 static bool do_sframe = false;
244 static bool do_arch = false;
245 static bool do_notes = false;
246 static bool do_archive_index = false;
247 static bool check_all = false;
248 static bool is_32bit_elf = false;
249 static bool decompress_dumps = false;
250 static bool do_not_show_symbol_truncation = false;
251 static bool do_demangle = false; /* Pretty print C++ symbol names. */
252 static bool process_links = false;
253 static bool dump_any_debugging = false;
254 static bool extra_sym_info = false;
255 static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
256 static int sym_base = 0;
258 static char *dump_ctf_parent_name;
259 static char *dump_ctf_symtab_name;
260 static char *dump_ctf_strtab_name;
262 struct group_list
264 struct group_list * next;
265 unsigned int section_index;
268 struct group
270 struct group_list * root;
271 unsigned int group_index;
274 typedef struct filedata
276 const char * file_name;
277 bool is_separate;
278 FILE * handle;
279 uint64_t file_size;
280 Elf_Internal_Ehdr file_header;
281 uint64_t archive_file_offset;
282 uint64_t archive_file_size;
283 /* Everything below this point is cleared out by free_filedata. */
284 Elf_Internal_Shdr * section_headers;
285 Elf_Internal_Phdr * program_headers;
286 char * string_table;
287 uint64_t string_table_length;
288 uint64_t dynamic_addr;
289 uint64_t dynamic_size;
290 uint64_t dynamic_nent;
291 Elf_Internal_Dyn * dynamic_section;
292 Elf_Internal_Shdr * dynamic_strtab_section;
293 char * dynamic_strings;
294 uint64_t dynamic_strings_length;
295 Elf_Internal_Shdr * dynamic_symtab_section;
296 uint64_t num_dynamic_syms;
297 Elf_Internal_Sym * dynamic_symbols;
298 uint64_t version_info[16];
299 unsigned int dynamic_syminfo_nent;
300 Elf_Internal_Syminfo * dynamic_syminfo;
301 uint64_t dynamic_syminfo_offset;
302 uint64_t nbuckets;
303 uint64_t nchains;
304 uint64_t * buckets;
305 uint64_t * chains;
306 uint64_t ngnubuckets;
307 uint64_t ngnuchains;
308 uint64_t * gnubuckets;
309 uint64_t * gnuchains;
310 uint64_t * mipsxlat;
311 uint64_t gnusymidx;
312 char * program_interpreter;
313 uint64_t dynamic_info[DT_RELRENT + 1];
314 uint64_t dynamic_info_DT_GNU_HASH;
315 uint64_t dynamic_info_DT_MIPS_XHASH;
316 elf_section_list * symtab_shndx_list;
317 size_t group_count;
318 struct group * section_groups;
319 struct group ** section_headers_groups;
320 /* A dynamic array of flags indicating for which sections a dump of
321 some kind has been requested. It is reset on a per-object file
322 basis and then initialised from the cmdline_dump_sects array,
323 the results of interpreting the -w switch, and the
324 dump_sects_byname list. */
325 struct dump_data dump;
326 } Filedata;
328 /* How to print a vma value. */
329 typedef enum print_mode
331 HEX,
332 HEX_5,
333 DEC,
334 DEC_5,
335 UNSIGNED,
336 UNSIGNED_5,
337 PREFIX_HEX,
338 PREFIX_HEX_5,
339 FULL_HEX,
340 LONG_HEX,
341 ZERO_HEX,
342 OCTAL,
343 OCTAL_5
345 print_mode;
347 typedef enum unicode_display_type
349 unicode_default = 0,
350 unicode_locale,
351 unicode_escape,
352 unicode_hex,
353 unicode_highlight,
354 unicode_invalid
355 } unicode_display_type;
357 static unicode_display_type unicode_display = unicode_default;
359 typedef enum
361 reltype_unknown,
362 reltype_rel,
363 reltype_rela,
364 reltype_relr
365 } relocation_type;
367 /* Versioned symbol info. */
368 enum versioned_symbol_info
370 symbol_undefined,
371 symbol_hidden,
372 symbol_public
375 static int
376 fseek64 (FILE *stream, int64_t offset, int whence)
378 #if defined (HAVE_FSEEKO64)
379 off64_t o = offset;
380 if (o != offset)
382 errno = EINVAL;
383 return -1;
385 return fseeko64 (stream, o, whence);
386 #elif defined (HAVE_FSEEKO)
387 off_t o = offset;
388 if (o != offset)
390 errno = EINVAL;
391 return -1;
393 return fseeko (stream, o, whence);
394 #else
395 long o = offset;
396 if (o != offset)
398 errno = EINVAL;
399 return -1;
401 return fseek (stream, o, whence);
402 #endif
405 static const char * get_symbol_version_string
406 (Filedata *, bool, const char *, size_t, unsigned,
407 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
409 static bool process_notes_at
410 (Filedata *, Elf_Internal_Shdr *, uint64_t, uint64_t, uint64_t);
412 #define UNKNOWN -1
414 static inline const char *
415 section_name (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
417 return filedata->string_table + hdr->sh_name;
420 static inline bool
421 section_name_valid (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
423 return (filedata != NULL
424 && hdr != NULL
425 && filedata->string_table != NULL
426 && hdr->sh_name < filedata->string_table_length);
429 /* Returns true if the given index is real/valid. Note: "real" here
430 means "references a real section in the section header" and not
431 "is a valid section index as per the ELF standard". */
433 static inline bool
434 section_index_real (const Filedata *filedata, unsigned int ndx)
436 return (filedata != NULL
437 && filedata->section_headers != NULL
438 && ndx < filedata->file_header.e_shnum
439 && ndx > 0);
442 #define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
444 static inline bool
445 valid_symbol_name (const char *strtab, size_t strtab_size, uint64_t offset)
447 return strtab != NULL && offset < strtab_size;
450 static inline bool
451 valid_dynamic_name (const Filedata *filedata, uint64_t offset)
453 return valid_symbol_name (filedata->dynamic_strings,
454 filedata->dynamic_strings_length, offset);
457 /* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
458 already been called and verified that the string exists. */
459 static inline const char *
460 get_dynamic_name (const Filedata *filedata, size_t offset)
462 return filedata->dynamic_strings + offset;
465 #define REMOVE_ARCH_BITS(ADDR) \
466 do \
468 if (filedata->file_header.e_machine == EM_ARM) \
469 (ADDR) &= ~1; \
471 while (0)
473 /* Get the correct GNU hash section name. */
474 #define GNU_HASH_SECTION_NAME(filedata) \
475 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
477 /* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
478 OFFSET + the offset of the current archive member, if we are examining an
479 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
480 allocate a buffer using malloc and fill that. In either case return the
481 pointer to the start of the retrieved data or NULL if something went wrong.
482 If something does go wrong and REASON is not NULL then emit an error
483 message using REASON as part of the context. */
485 static void *
486 get_data (void *var,
487 Filedata *filedata,
488 uint64_t offset,
489 uint64_t size,
490 uint64_t nmemb,
491 const char *reason)
493 void * mvar;
494 uint64_t amt = size * nmemb;
496 if (size == 0 || nmemb == 0)
497 return NULL;
499 /* If size_t is smaller than uint64_t, eg because you are building
500 on a 32-bit host, then make sure that when the sizes are cast to
501 size_t no information is lost. */
502 if ((size_t) size != size
503 || (size_t) nmemb != nmemb
504 || (size_t) amt != amt
505 || amt / size != nmemb
506 || (size_t) amt + 1 == 0)
508 if (reason)
509 error (_("Size overflow prevents reading %" PRIu64
510 " elements of size %" PRIu64 " for %s\n"),
511 nmemb, size, reason);
512 return NULL;
515 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
516 attempting to allocate memory when the read is bound to fail. */
517 if (filedata->archive_file_offset > filedata->file_size
518 || offset > filedata->file_size - filedata->archive_file_offset
519 || amt > filedata->file_size - filedata->archive_file_offset - offset)
521 if (reason)
522 error (_("Reading %" PRIu64 " bytes extends past end of file for %s\n"),
523 amt, reason);
524 return NULL;
527 if (fseek64 (filedata->handle, filedata->archive_file_offset + offset,
528 SEEK_SET))
530 if (reason)
531 error (_("Unable to seek to %#" PRIx64 " for %s\n"),
532 filedata->archive_file_offset + offset, reason);
533 return NULL;
536 mvar = var;
537 if (mvar == NULL)
539 /* + 1 so that we can '\0' terminate invalid string table sections. */
540 mvar = malloc ((size_t) amt + 1);
542 if (mvar == NULL)
544 if (reason)
545 error (_("Out of memory allocating %" PRIu64 " bytes for %s\n"),
546 amt, reason);
547 return NULL;
550 ((char *) mvar)[amt] = '\0';
553 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
555 if (reason)
556 error (_("Unable to read in %" PRIu64 " bytes of %s\n"),
557 amt, reason);
558 if (mvar != var)
559 free (mvar);
560 return NULL;
563 return mvar;
566 /* Print a VMA value in the MODE specified.
567 Returns the number of characters displayed. */
569 static unsigned int
570 print_vma (uint64_t vma, print_mode mode)
572 unsigned int nc = 0;
574 switch (mode)
576 case FULL_HEX:
577 nc = printf ("0x");
578 /* Fall through. */
579 case LONG_HEX:
580 if (!is_32bit_elf)
581 return nc + printf ("%16.16" PRIx64, vma);
582 return nc + printf ("%8.8" PRIx64, vma);
584 case ZERO_HEX:
585 if (is_32bit_elf)
586 return printf ("%08" PRIx64, vma);
587 return printf ("%016" PRIx64, vma);
589 case DEC_5:
590 if (vma <= 99999)
591 return printf ("%5" PRId64, vma);
592 /* Fall through. */
593 case PREFIX_HEX:
594 nc = printf ("0x");
595 /* Fall through. */
596 case HEX:
597 return nc + printf ("%" PRIx64, vma);
599 case PREFIX_HEX_5:
600 nc = printf ("0x");
601 /* Fall through. */
602 case HEX_5:
603 return nc + printf ("%05" PRIx64, vma);
605 case DEC:
606 return printf ("%" PRId64, vma);
608 case UNSIGNED:
609 return printf ("%" PRIu64, vma);
611 case UNSIGNED_5:
612 return printf ("%5" PRIu64, vma);
614 case OCTAL:
615 return printf ("%" PRIo64, vma);
617 case OCTAL_5:
618 return printf ("%5" PRIo64, vma);
620 default:
621 /* FIXME: Report unrecognised mode ? */
622 return 0;
627 /* Display a symbol on stdout. Handles the display of control characters and
628 multibye characters (assuming the host environment supports them).
630 Display at most abs(WIDTH) characters, truncating as necessary,
631 unless do_wide or extra_sym_info is true.
633 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
634 abs(WIDTH) - 5 characters followed by "[...]".
636 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
637 padding as necessary.
639 Returns the number of emitted characters. */
641 static unsigned int
642 print_symbol_name (signed int width, const char * symbol)
644 bool extra_padding = false;
645 bool do_dots = false;
646 signed int num_printed = 0;
647 #ifdef HAVE_MBSTATE_T
648 mbstate_t state;
649 #endif
650 unsigned int width_remaining;
651 const void * alloced_symbol = NULL;
653 if (width < 0)
655 /* Keep the width positive. This helps the code below. */
656 width = - width;
657 extra_padding = true;
659 else if (width == 0)
660 return 0;
662 if (do_wide || extra_sym_info)
663 /* Set the remaining width to a very large value.
664 This simplifies the code below. */
665 width_remaining = INT_MAX;
666 else
668 width_remaining = width;
670 if (! do_not_show_symbol_truncation
671 && (int) strlen (symbol) > width)
673 width_remaining -= 5;
674 if ((int) width_remaining < 0)
675 width_remaining = 0;
676 do_dots = true;
680 #ifdef HAVE_MBSTATE_T
681 /* Initialise the multibyte conversion state. */
682 memset (& state, 0, sizeof (state));
683 #endif
685 if (do_demangle && *symbol)
687 const char * res = cplus_demangle (symbol, demangle_flags);
689 if (res != NULL)
690 alloced_symbol = symbol = res;
693 while (width_remaining)
695 size_t n;
696 const char c = *symbol++;
698 if (c == 0)
699 break;
701 if (ISPRINT (c))
703 putchar (c);
704 width_remaining --;
705 num_printed ++;
707 else if (ISCNTRL (c))
709 /* Do not print control characters directly as they can affect terminal
710 settings. Such characters usually appear in the names generated
711 by the assembler for local labels. */
713 if (width_remaining < 2)
714 break;
716 printf ("^%c", c + 0x40);
717 width_remaining -= 2;
718 num_printed += 2;
720 else if (c == 0x7f)
722 if (width_remaining < 5)
723 break;
724 printf ("<DEL>");
725 width_remaining -= 5;
726 num_printed += 5;
728 else if (unicode_display != unicode_locale
729 && unicode_display != unicode_default)
731 /* Display unicode characters as something else. */
732 unsigned char bytes[4];
733 bool is_utf8;
734 unsigned int nbytes;
736 bytes[0] = c;
738 if (bytes[0] < 0xc0)
740 nbytes = 1;
741 is_utf8 = false;
743 else
745 bytes[1] = *symbol++;
747 if ((bytes[1] & 0xc0) != 0x80)
749 is_utf8 = false;
750 /* Do not consume this character. It may only
751 be the first byte in the sequence that was
752 corrupt. */
753 --symbol;
754 nbytes = 1;
756 else if ((bytes[0] & 0x20) == 0)
758 is_utf8 = true;
759 nbytes = 2;
761 else
763 bytes[2] = *symbol++;
765 if ((bytes[2] & 0xc0) != 0x80)
767 is_utf8 = false;
768 symbol -= 2;
769 nbytes = 1;
771 else if ((bytes[0] & 0x10) == 0)
773 is_utf8 = true;
774 nbytes = 3;
776 else
778 bytes[3] = *symbol++;
780 nbytes = 4;
782 if ((bytes[3] & 0xc0) != 0x80)
784 is_utf8 = false;
785 symbol -= 3;
786 nbytes = 1;
788 else
789 is_utf8 = true;
794 if (unicode_display == unicode_invalid)
795 is_utf8 = false;
797 if (unicode_display == unicode_hex || ! is_utf8)
799 unsigned int i;
801 if (width_remaining < (nbytes * 2) + 2)
802 break;
804 putchar (is_utf8 ? '<' : '{');
805 printf ("0x");
806 for (i = 0; i < nbytes; i++)
807 printf ("%02x", bytes[i]);
808 putchar (is_utf8 ? '>' : '}');
810 else
812 if (unicode_display == unicode_highlight && isatty (1))
813 printf ("\x1B[31;47m"); /* Red. */
815 switch (nbytes)
817 case 2:
818 if (width_remaining < 6)
819 break;
820 printf ("\\u%02x%02x",
821 (bytes[0] & 0x1c) >> 2,
822 ((bytes[0] & 0x03) << 6) | (bytes[1] & 0x3f));
823 break;
824 case 3:
825 if (width_remaining < 6)
826 break;
827 printf ("\\u%02x%02x",
828 ((bytes[0] & 0x0f) << 4) | ((bytes[1] & 0x3c) >> 2),
829 ((bytes[1] & 0x03) << 6) | (bytes[2] & 0x3f));
830 break;
831 case 4:
832 if (width_remaining < 8)
833 break;
834 printf ("\\u%02x%02x%02x",
835 ((bytes[0] & 0x07) << 6) | ((bytes[1] & 0x3c) >> 2),
836 ((bytes[1] & 0x03) << 6) | ((bytes[2] & 0x3c) >> 2),
837 ((bytes[2] & 0x03) << 6) | (bytes[3] & 0x3f));
839 break;
840 default:
841 /* URG. */
842 break;
845 if (unicode_display == unicode_highlight && isatty (1))
846 printf ("\033[0m"); /* Default colour. */
849 if (bytes[nbytes - 1] == 0)
850 break;
852 else
854 #ifdef HAVE_MBSTATE_T
855 wchar_t w;
856 #endif
857 /* Let printf do the hard work of displaying multibyte characters. */
858 printf ("%.1s", symbol - 1);
859 width_remaining --;
860 num_printed ++;
862 #ifdef HAVE_MBSTATE_T
863 /* Try to find out how many bytes made up the character that was
864 just printed. Advance the symbol pointer past the bytes that
865 were displayed. */
866 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
867 #else
868 n = 1;
869 #endif
870 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
871 symbol += (n - 1);
875 if (do_dots)
876 num_printed += printf ("[...]");
878 if (extra_padding && num_printed < width)
880 /* Fill in the remaining spaces. */
881 printf ("%-*s", width - num_printed, " ");
882 num_printed = width;
885 free ((void *) alloced_symbol);
886 return num_printed;
889 /* Returns a pointer to a static buffer containing a printable version of
890 STRING. Uses a rotating array of static buffers, so that multiple
891 successive calls will still work. eg when used in a call to printf().
893 If supplied MAX_LEN is the maximum number of characters to be read
894 starting from STRING.
896 This function is similar to print_symbol_name(), except that it does
897 not try to print multibyte characters, it just shows them as hex values.
899 If the string is too long for the static buffer or if it is not
900 terminated then a truncated version of the string will be returned. */
902 static const char *
903 printable_string (const char * string, unsigned int max_len)
905 #define NUM_STRING_BUFS 5
906 #define MAX_STRING_LEN 256
908 static int string_buf_index = 0;
909 static char string_buf [NUM_STRING_BUFS][MAX_STRING_LEN + 1];
911 char * buf;
912 char * buf_start;
914 /* Select a buffer to use. */
915 buf_start = buf = string_buf[string_buf_index];
916 if (++ string_buf_index >= NUM_STRING_BUFS)
917 string_buf_index = 0;
919 char c;
920 unsigned int remaining = MAX_STRING_LEN;
922 while ((c = * string ++) != 0)
924 if (ISCNTRL (c))
926 if (remaining < 2)
927 break;
929 * buf ++ = '^';
930 * buf ++ = c + 0x40;
931 remaining -= 2;
933 else if (ISPRINT (c))
935 * buf ++ = c;
936 remaining -= 1;
938 else
940 static char hex[17] = "0123456789ABCDEF";
942 if (remaining < 4)
943 break;
944 * buf ++ = '<';
945 * buf ++ = hex[(c & 0xf0) >> 4];
946 * buf ++ = hex[c & 0x0f];
947 * buf ++ = '>';
948 remaining -= 4;
951 if (remaining == 0)
952 break;
954 if (max_len > 0)
956 max_len -= 1;
957 if (max_len == 0)
958 break;
962 * buf = 0;
963 return buf_start;
966 /* Returns a pointer to a static buffer containing a
967 printable version of the given section's name. */
969 static const char *
970 printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
972 /* Validate the input parameters. */
973 if (filedata == NULL)
974 return _("<internal error>");
975 if (sec == NULL)
976 return _("<none>");
977 if (filedata->string_table == NULL)
978 return _("<no-strings>");
979 if (sec->sh_name >= filedata->string_table_length)
980 return _("<corrupt>");
982 return printable_string (section_name (filedata, sec),
983 filedata->string_table_length - sec->sh_name);
986 /* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
987 This OS has so many departures from the ELF standard that we test it at
988 many places. */
990 static inline bool
991 is_ia64_vms (Filedata * filedata)
993 return filedata->file_header.e_machine == EM_IA_64
994 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
997 static const char *
998 printable_section_name_from_index (Filedata * filedata,
999 size_t ndx,
1000 bool * is_special)
1002 if (is_special != NULL)
1003 * is_special = true;
1005 switch (ndx)
1007 case SHN_UNDEF: return "UND";
1008 case SHN_ABS: return "ABS";
1009 case SHN_COMMON: return "COM";
1010 break;
1013 if (filedata != NULL)
1015 switch (filedata->file_header.e_machine)
1017 case EM_MIPS:
1018 if (ndx == SHN_MIPS_SCOMMON)
1019 return "SCOMMON";
1020 if (ndx == SHN_MIPS_SUNDEFINED)
1021 return "SUNDEF";
1022 break;
1024 case EM_TI_C6000:
1025 if (ndx == SHN_TIC6X_SCOMMON)
1026 return "SCOM";
1027 break;
1029 case EM_X86_64:
1030 case EM_L1OM:
1031 case EM_K1OM:
1032 if (ndx == SHN_X86_64_LCOMMON)
1033 return "LARGE_COM";
1034 break;
1036 case EM_IA_64:
1037 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1038 && ndx == SHN_IA_64_ANSI_COMMON)
1039 return "ANSI_COM";
1041 if (is_ia64_vms (filedata) && ndx == SHN_IA_64_VMS_SYMVEC)
1042 return "VMS_SYMVEC";
1043 break;
1045 default:
1046 break;
1049 if (filedata->section_headers != NULL
1050 && ndx < filedata->file_header.e_shnum)
1052 const char * res;
1054 res = printable_section_name (filedata, filedata->section_headers + ndx);
1055 if (is_special != NULL)
1056 * is_special = (res[0] == '<');
1058 return res;
1062 static char name_buf[40];
1063 unsigned int short_ndx = (unsigned int) (ndx & 0xffff);
1065 if (ndx >= SHN_LOPROC && ndx <= SHN_HIPROC)
1066 sprintf (name_buf, "PRC[0x%04x]", short_ndx);
1067 else if (ndx >= SHN_LOOS && ndx <= SHN_HIOS)
1068 sprintf (name_buf, "OS [0x%04x]", short_ndx);
1069 else if (ndx >= SHN_LORESERVE)
1070 sprintf (name_buf, "RSV[0x%04x]", short_ndx);
1071 else if (filedata->file_header.e_shnum != 0
1072 && ndx >= filedata->file_header.e_shnum)
1073 sprintf (name_buf, _("BAD[0x%lx]"), (long) ndx);
1074 else
1075 sprintf (name_buf, "<section 0x%lx>", (long) ndx);
1077 return name_buf;
1080 /* Return a pointer to section NAME, or NULL if no such section exists. */
1082 static Elf_Internal_Shdr *
1083 find_section (Filedata * filedata, const char * name)
1085 unsigned int i;
1087 if (filedata->section_headers == NULL)
1088 return NULL;
1090 for (i = 0; i < filedata->file_header.e_shnum; i++)
1091 if (section_name_valid (filedata, filedata->section_headers + i)
1092 && streq (section_name (filedata, filedata->section_headers + i),
1093 name))
1094 return filedata->section_headers + i;
1096 return NULL;
1099 /* Return a pointer to a section containing ADDR, or NULL if no such
1100 section exists. */
1102 static Elf_Internal_Shdr *
1103 find_section_by_address (Filedata * filedata, uint64_t addr)
1105 unsigned int i;
1107 if (filedata->section_headers == NULL)
1108 return NULL;
1110 for (i = 0; i < filedata->file_header.e_shnum; i++)
1112 Elf_Internal_Shdr *sec = filedata->section_headers + i;
1114 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
1115 return sec;
1118 return NULL;
1121 static Elf_Internal_Shdr *
1122 find_section_by_type (Filedata * filedata, unsigned int type)
1124 unsigned int i;
1126 if (filedata->section_headers == NULL)
1127 return NULL;
1129 for (i = 0; i < filedata->file_header.e_shnum; i++)
1131 Elf_Internal_Shdr *sec = filedata->section_headers + i;
1133 if (sec->sh_type == type)
1134 return sec;
1137 return NULL;
1140 static Elf_Internal_Shdr *
1141 find_section_by_name (Filedata * filedata, const char * name)
1143 unsigned int i;
1145 if (filedata->section_headers == NULL || filedata->string_table_length == 0)
1146 return NULL;
1148 for (i = 0; i < filedata->file_header.e_shnum; i++)
1150 Elf_Internal_Shdr *sec = filedata->section_headers + i;
1152 if (sec->sh_name < filedata->string_table_length
1153 && streq (name, filedata->string_table + sec->sh_name))
1154 return sec;
1157 return NULL;
1160 /* Return a pointer to section NAME, or NULL if no such section exists,
1161 restricted to the list of sections given in SET. */
1163 static Elf_Internal_Shdr *
1164 find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
1166 unsigned int i;
1168 if (filedata->section_headers == NULL)
1169 return NULL;
1171 if (set != NULL)
1173 while ((i = *set++) > 0)
1175 /* See PR 21156 for a reproducer. */
1176 if (i >= filedata->file_header.e_shnum)
1177 continue; /* FIXME: Should we issue an error message ? */
1179 if (section_name_valid (filedata, filedata->section_headers + i)
1180 && streq (section_name (filedata, filedata->section_headers + i),
1181 name))
1182 return filedata->section_headers + i;
1186 return find_section (filedata, name);
1189 /* Guess the relocation size commonly used by the specific machines. */
1191 static bool
1192 guess_is_rela (unsigned int e_machine)
1194 switch (e_machine)
1196 /* Targets that use REL relocations. */
1197 case EM_386:
1198 case EM_IAMCU:
1199 case EM_960:
1200 case EM_ARM:
1201 case EM_D10V:
1202 case EM_CYGNUS_D10V:
1203 case EM_DLX:
1204 case EM_MIPS:
1205 case EM_MIPS_RS3_LE:
1206 case EM_CYGNUS_M32R:
1207 case EM_SCORE:
1208 case EM_XGATE:
1209 case EM_NFP:
1210 case EM_BPF:
1211 return false;
1213 /* Targets that use RELA relocations. */
1214 case EM_68K:
1215 case EM_860:
1216 case EM_AARCH64:
1217 case EM_ADAPTEVA_EPIPHANY:
1218 case EM_ALPHA:
1219 case EM_ALTERA_NIOS2:
1220 case EM_ARC:
1221 case EM_ARC_COMPACT:
1222 case EM_ARC_COMPACT2:
1223 case EM_ARC_COMPACT3:
1224 case EM_ARC_COMPACT3_64:
1225 case EM_AVR:
1226 case EM_AVR_OLD:
1227 case EM_BLACKFIN:
1228 case EM_CR16:
1229 case EM_CRIS:
1230 case EM_CRX:
1231 case EM_CSKY:
1232 case EM_D30V:
1233 case EM_CYGNUS_D30V:
1234 case EM_FR30:
1235 case EM_FT32:
1236 case EM_CYGNUS_FR30:
1237 case EM_CYGNUS_FRV:
1238 case EM_H8S:
1239 case EM_H8_300:
1240 case EM_H8_300H:
1241 case EM_IA_64:
1242 case EM_IP2K:
1243 case EM_IP2K_OLD:
1244 case EM_IQ2000:
1245 case EM_KVX:
1246 case EM_LATTICEMICO32:
1247 case EM_M32C_OLD:
1248 case EM_M32C:
1249 case EM_M32R:
1250 case EM_MCORE:
1251 case EM_CYGNUS_MEP:
1252 case EM_METAG:
1253 case EM_MMIX:
1254 case EM_MN10200:
1255 case EM_CYGNUS_MN10200:
1256 case EM_MN10300:
1257 case EM_CYGNUS_MN10300:
1258 case EM_MOXIE:
1259 case EM_MSP430:
1260 case EM_MSP430_OLD:
1261 case EM_MT:
1262 case EM_NDS32:
1263 case EM_NIOS32:
1264 case EM_OR1K:
1265 case EM_PPC64:
1266 case EM_PPC:
1267 case EM_TI_PRU:
1268 case EM_RISCV:
1269 case EM_RL78:
1270 case EM_RX:
1271 case EM_S390:
1272 case EM_S390_OLD:
1273 case EM_SH:
1274 case EM_SPARC:
1275 case EM_SPARC32PLUS:
1276 case EM_SPARCV9:
1277 case EM_SPU:
1278 case EM_TI_C6000:
1279 case EM_TILEGX:
1280 case EM_TILEPRO:
1281 case EM_V800:
1282 case EM_V850:
1283 case EM_CYGNUS_V850:
1284 case EM_VAX:
1285 case EM_VISIUM:
1286 case EM_X86_64:
1287 case EM_L1OM:
1288 case EM_K1OM:
1289 case EM_XSTORMY16:
1290 case EM_XTENSA:
1291 case EM_XTENSA_OLD:
1292 case EM_MICROBLAZE:
1293 case EM_MICROBLAZE_OLD:
1294 case EM_WEBASSEMBLY:
1295 return true;
1297 case EM_68HC05:
1298 case EM_68HC08:
1299 case EM_68HC11:
1300 case EM_68HC16:
1301 case EM_FX66:
1302 case EM_ME16:
1303 case EM_MMA:
1304 case EM_NCPU:
1305 case EM_NDR1:
1306 case EM_PCP:
1307 case EM_ST100:
1308 case EM_ST19:
1309 case EM_ST7:
1310 case EM_ST9PLUS:
1311 case EM_STARCORE:
1312 case EM_SVX:
1313 case EM_TINYJ:
1314 default:
1315 warn (_("Don't know about relocations on this machine architecture\n"));
1316 return false;
1320 /* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
1321 Returns TRUE upon success, FALSE otherwise. If successful then a
1322 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
1323 and the number of relocs loaded is placed in *NRELASP. It is the caller's
1324 responsibility to free the allocated buffer. */
1326 static bool
1327 slurp_rela_relocs (Filedata *filedata,
1328 uint64_t rel_offset,
1329 uint64_t rel_size,
1330 Elf_Internal_Rela **relasp,
1331 uint64_t *nrelasp)
1333 Elf_Internal_Rela * relas;
1334 uint64_t nrelas;
1335 unsigned int i;
1337 if (is_32bit_elf)
1339 Elf32_External_Rela * erelas;
1341 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
1342 rel_size, _("32-bit relocation data"));
1343 if (!erelas)
1344 return false;
1346 nrelas = rel_size / sizeof (Elf32_External_Rela);
1348 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1349 sizeof (Elf_Internal_Rela));
1351 if (relas == NULL)
1353 free (erelas);
1354 error (_("out of memory parsing relocs\n"));
1355 return false;
1358 for (i = 0; i < nrelas; i++)
1360 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1361 relas[i].r_info = BYTE_GET (erelas[i].r_info);
1362 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
1365 free (erelas);
1367 else
1369 Elf64_External_Rela * erelas;
1371 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
1372 rel_size, _("64-bit relocation data"));
1373 if (!erelas)
1374 return false;
1376 nrelas = rel_size / sizeof (Elf64_External_Rela);
1378 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1379 sizeof (Elf_Internal_Rela));
1381 if (relas == NULL)
1383 free (erelas);
1384 error (_("out of memory parsing relocs\n"));
1385 return false;
1388 for (i = 0; i < nrelas; i++)
1390 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1391 relas[i].r_info = BYTE_GET (erelas[i].r_info);
1392 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
1394 if (filedata->file_header.e_machine == EM_MIPS
1395 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
1397 /* In little-endian objects, r_info isn't really a
1398 64-bit little-endian value: it has a 32-bit
1399 little-endian symbol index followed by four
1400 individual byte fields. Reorder INFO
1401 accordingly. */
1402 uint64_t inf = relas[i].r_info;
1403 inf = (((inf & 0xffffffff) << 32)
1404 | ((inf >> 56) & 0xff)
1405 | ((inf >> 40) & 0xff00)
1406 | ((inf >> 24) & 0xff0000)
1407 | ((inf >> 8) & 0xff000000));
1408 relas[i].r_info = inf;
1412 free (erelas);
1415 *relasp = relas;
1416 *nrelasp = nrelas;
1417 return true;
1420 /* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
1421 Returns TRUE upon success, FALSE otherwise. If successful then a
1422 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1423 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1424 responsibility to free the allocated buffer. */
1426 static bool
1427 slurp_rel_relocs (Filedata *filedata,
1428 uint64_t rel_offset,
1429 uint64_t rel_size,
1430 Elf_Internal_Rela **relsp,
1431 uint64_t *nrelsp)
1433 Elf_Internal_Rela * rels;
1434 uint64_t nrels;
1435 unsigned int i;
1437 if (is_32bit_elf)
1439 Elf32_External_Rel * erels;
1441 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
1442 rel_size, _("32-bit relocation data"));
1443 if (!erels)
1444 return false;
1446 nrels = rel_size / sizeof (Elf32_External_Rel);
1448 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
1450 if (rels == NULL)
1452 free (erels);
1453 error (_("out of memory parsing relocs\n"));
1454 return false;
1457 for (i = 0; i < nrels; i++)
1459 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1460 rels[i].r_info = BYTE_GET (erels[i].r_info);
1461 rels[i].r_addend = 0;
1464 free (erels);
1466 else
1468 Elf64_External_Rel * erels;
1470 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
1471 rel_size, _("64-bit relocation data"));
1472 if (!erels)
1473 return false;
1475 nrels = rel_size / sizeof (Elf64_External_Rel);
1477 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
1479 if (rels == NULL)
1481 free (erels);
1482 error (_("out of memory parsing relocs\n"));
1483 return false;
1486 for (i = 0; i < nrels; i++)
1488 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1489 rels[i].r_info = BYTE_GET (erels[i].r_info);
1490 rels[i].r_addend = 0;
1492 if (filedata->file_header.e_machine == EM_MIPS
1493 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
1495 /* In little-endian objects, r_info isn't really a
1496 64-bit little-endian value: it has a 32-bit
1497 little-endian symbol index followed by four
1498 individual byte fields. Reorder INFO
1499 accordingly. */
1500 uint64_t inf = rels[i].r_info;
1501 inf = (((inf & 0xffffffff) << 32)
1502 | ((inf >> 56) & 0xff)
1503 | ((inf >> 40) & 0xff00)
1504 | ((inf >> 24) & 0xff0000)
1505 | ((inf >> 8) & 0xff000000));
1506 rels[i].r_info = inf;
1510 free (erels);
1513 *relsp = rels;
1514 *nrelsp = nrels;
1515 return true;
1518 /* Returns the reloc type extracted from the reloc info field. */
1520 static unsigned int
1521 get_reloc_type (Filedata * filedata, uint64_t reloc_info)
1523 if (is_32bit_elf)
1524 return ELF32_R_TYPE (reloc_info);
1526 switch (filedata->file_header.e_machine)
1528 case EM_MIPS:
1529 /* Note: We assume that reloc_info has already been adjusted for us. */
1530 return ELF64_MIPS_R_TYPE (reloc_info);
1532 case EM_SPARCV9:
1533 return ELF64_R_TYPE_ID (reloc_info);
1535 default:
1536 return ELF64_R_TYPE (reloc_info);
1540 /* Return the symbol index extracted from the reloc info field. */
1542 static uint64_t
1543 get_reloc_symindex (uint64_t reloc_info)
1545 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1548 static inline bool
1549 uses_msp430x_relocs (Filedata * filedata)
1551 return
1552 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
1553 /* GCC uses osabi == ELFOSBI_STANDALONE. */
1554 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
1555 /* TI compiler uses ELFOSABI_NONE. */
1556 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
1560 static const char *
1561 get_symbol_at (Filedata * filedata,
1562 Elf_Internal_Sym * symtab,
1563 uint64_t nsyms,
1564 char * strtab,
1565 uint64_t where,
1566 uint64_t * offset_return)
1568 Elf_Internal_Sym * beg = symtab;
1569 Elf_Internal_Sym * end = symtab + nsyms;
1570 Elf_Internal_Sym * best = NULL;
1571 uint64_t dist = 0x100000;
1573 /* FIXME: Since this function is likely to be called repeatedly with
1574 slightly increasing addresses each time, we could speed things up by
1575 caching the last returned value and starting our search from there. */
1576 while (beg < end)
1578 Elf_Internal_Sym * sym;
1579 uint64_t value;
1581 sym = beg + (end - beg) / 2;
1583 value = sym->st_value;
1585 if (where >= value
1586 && where - value < dist)
1588 best = sym;
1589 dist = where - value;
1590 if (dist == 0)
1591 break;
1594 if (where < value)
1595 end = sym;
1596 else
1597 beg = sym + 1;
1600 const char *name;
1602 /* If there is a section start closer than the found symbol then
1603 use that for symbolizing the address. */
1604 Elf_Internal_Shdr *sec = find_section_by_address (filedata, where);
1605 if (sec != NULL
1606 && where - sec->sh_addr < dist
1607 && section_name_valid (filedata, sec))
1609 name = section_name (filedata, sec);
1610 dist = where - sec->sh_addr;
1612 else if (best != NULL)
1613 name = strtab + best->st_name;
1614 else
1615 return NULL;
1617 if (offset_return != NULL)
1618 * offset_return = dist;
1620 return name;
1623 static void
1624 print_relr_addr_and_sym (Filedata * filedata,
1625 Elf_Internal_Sym * symtab,
1626 uint64_t nsyms,
1627 char * strtab,
1628 uint64_t where)
1630 const char * symname = NULL;
1631 uint64_t offset = 0;
1633 print_vma (where, ZERO_HEX);
1634 printf (" ");
1636 symname = get_symbol_at (filedata, symtab, nsyms, strtab, where, & offset);
1638 if (symname == NULL)
1639 printf ("<no sym>");
1640 else if (offset == 0)
1641 print_symbol_name (38, symname);
1642 else
1644 print_symbol_name (28, symname);
1645 printf (" + ");
1646 print_vma (offset, PREFIX_HEX);
1650 /* See bfd_is_aarch64_special_symbol_name. */
1652 static bool
1653 is_aarch64_special_symbol_name (const char *name)
1655 if (!name || name[0] != '$')
1656 return false;
1657 if (name[1] == 'x' || name[1] == 'd')
1658 /* Map. */;
1659 else if (name[1] == 'm' || name[1] == 'f' || name[1] == 'p')
1660 /* Tag. */;
1661 else
1662 return false;
1663 return name[2] == 0 || name[2] == '.';
1666 static bool
1667 is_special_symbol_name (Filedata * filedata, const char * s)
1669 switch (filedata->file_header.e_machine)
1671 case EM_AARCH64:
1672 return is_aarch64_special_symbol_name (s);
1674 default:
1675 return false;
1679 /* Allows selecting the best symbol from a set for displaying addresses.
1680 BEST is the current best or NULL if there are no good symbols yet.
1681 SYM is the next symbol to consider, if it is better than BEST then
1682 return SYM else return BEST. */
1684 static Elf_Internal_Sym *
1685 select_display_sym (Filedata * filedata,
1686 char * strtab,
1687 uint64_t strtablen,
1688 Elf_Internal_Sym * best,
1689 Elf_Internal_Sym * sym)
1691 /* Ignore empty or invalid syms. */
1692 if (sym->st_name == 0)
1693 return best;
1694 if (sym->st_name >= strtablen)
1695 return best;
1696 /* Ignore undefined or TLS syms. */
1697 if (sym->st_shndx == SHN_UNDEF)
1698 return best;
1699 if (ELF_ST_TYPE (sym->st_info) == STT_TLS)
1700 return best;
1702 char *s = strtab + sym->st_name;
1704 /* Don't display special symbols. */
1705 if (is_special_symbol_name (filedata, s))
1706 return best;
1708 /* Here SYM is good for display. */
1710 if (best == NULL)
1711 return sym;
1713 char *sbest = strtab + best->st_name;
1715 /* Prefer non-local symbols. */
1716 if (ELF_ST_BIND (sym->st_info) == STB_LOCAL
1717 && ELF_ST_BIND (best->st_info) != STB_LOCAL)
1718 return best;
1719 if (ELF_ST_BIND (sym->st_info) != STB_LOCAL
1720 && ELF_ST_BIND (best->st_info) == STB_LOCAL)
1721 return sym;
1723 /* Select based on lexicographic order. */
1724 return strcmp (s, sbest) < 0 ? sym : best;
1727 /* Filter the sorted SYMTAB symbol array in-place to select at most one
1728 symbol for an address and drop symbols that are not good to display.
1729 Returns the new array length. */
1731 static uint64_t
1732 filter_display_syms (Filedata * filedata,
1733 Elf_Internal_Sym * symtab,
1734 uint64_t nsyms,
1735 char * strtab,
1736 uint64_t strtablen)
1738 Elf_Internal_Sym *r = symtab;
1739 Elf_Internal_Sym *w = symtab;
1740 Elf_Internal_Sym *best = NULL;
1741 Elf_Internal_Sym *end = symtab + nsyms;
1742 while (r < end)
1744 /* Select the best symbol for an address. */
1745 while (r < end
1746 && (best == NULL || best->st_value == r->st_value))
1748 best = select_display_sym (filedata, strtab, strtablen, best, r);
1749 r++;
1751 if (best != NULL)
1753 *w = *best;
1754 w++;
1755 best = NULL;
1758 return w - symtab;
1761 static /* signed */ int
1762 symcmp (const void *p, const void *q)
1764 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
1765 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
1767 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
1770 static uint64_t
1771 count_relr_relocations (Filedata * filedata,
1772 Elf_Internal_Shdr * section)
1774 uint64_t * relrs;
1775 uint64_t nentries;
1776 uint64_t i;
1777 uint64_t count;
1778 int entsize;
1780 if (section == NULL
1781 || section->sh_type != SHT_RELR
1782 || section->sh_size == 0)
1783 return 0;
1785 entsize = section->sh_entsize;
1786 if (entsize == 0)
1787 entsize = is_32bit_elf
1788 ? sizeof (Elf32_External_Relr) : sizeof (Elf64_External_Relr);
1789 else if (entsize != sizeof (Elf32_External_Relr)
1790 && entsize != sizeof (Elf64_External_Relr))
1791 return 0;
1793 nentries = section->sh_size / entsize;
1794 if (nentries == 0)
1795 return 0;
1797 /* FIXME: This call to get_data duplicates one that follows in
1798 dump_relr_relocations(). They could be combined into just
1799 one call. */
1800 relrs = get_data (NULL, filedata, section->sh_offset, 1,
1801 section->sh_size, _("RELR relocation data"));
1802 if (relrs == NULL)
1803 return 0;
1805 for (count = i = 0; i < nentries; i++)
1807 uint64_t entry;
1809 if (entsize == sizeof (Elf32_External_Relr))
1810 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1811 else
1812 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1814 if ((entry & 1) == 0)
1816 ++ count;
1818 else
1820 if (entry == 1)
1821 continue;
1823 for (; entry >>= 1;)
1824 if ((entry & 1) == 1)
1825 ++ count;
1829 free (relrs);
1830 return count;
1833 static bool
1834 dump_relr_relocations (Filedata * filedata,
1835 Elf_Internal_Shdr * section,
1836 Elf_Internal_Sym * symtab,
1837 uint64_t nsyms,
1838 char * strtab,
1839 uint64_t strtablen)
1841 uint64_t * relrs;
1842 uint64_t nentries, i;
1843 uint64_t relr_size = section->sh_size;
1844 int relr_entsize = section->sh_entsize;
1845 uint64_t relr_offset = section->sh_offset;
1846 uint64_t where = 0;
1847 int num_bits_in_entry;
1849 if (relr_entsize == 0)
1850 relr_entsize = is_32bit_elf
1851 ? sizeof (Elf32_External_Relr) : sizeof (Elf64_External_Relr);
1853 nentries = relr_size / relr_entsize;
1855 if (nentries == 0)
1856 return true;
1858 if (relr_entsize == sizeof (Elf32_External_Relr))
1859 num_bits_in_entry = 31;
1860 else if (relr_entsize == sizeof (Elf64_External_Relr))
1861 num_bits_in_entry = 63;
1862 else
1864 warn (_("Unexpected entsize for RELR section\n"));
1865 return false;
1868 relrs = get_data (NULL, filedata, relr_offset, 1, relr_size, _("RELR relocation data"));
1869 if (relrs == NULL)
1870 return false;
1872 /* Paranoia. */
1873 if (strtab == NULL)
1874 strtablen = 0;
1875 if (symtab == NULL)
1876 nsyms = 0;
1878 if (symtab != NULL)
1880 /* Symbol tables are not sorted on address, but we want a quick lookup
1881 for the symbol associated with each address computed below, so sort
1882 the table then filter out unwanted entries. FIXME: This assumes that
1883 the symbol table will not be used later on for some other purpose. */
1884 qsort (symtab, nsyms, sizeof (Elf_Internal_Sym), symcmp);
1885 nsyms = filter_display_syms (filedata, symtab, nsyms, strtab, strtablen);
1888 if (relr_entsize == sizeof (Elf32_External_Relr))
1889 printf (_ ("Index: Entry Address Symbolic Address\n"));
1890 else
1891 printf (_ ("Index: Entry Address Symbolic Address\n"));
1893 for (i = 0; i < nentries; i++)
1895 uint64_t entry;
1897 if (relr_entsize == sizeof (Elf32_External_Relr))
1898 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1899 else
1900 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1902 /* We assume that there will never be more than 9999 entries. */
1903 printf (_("%04u: "), (unsigned int) i);
1904 print_vma (entry, ZERO_HEX);
1905 printf (" ");
1907 if ((entry & 1) == 0)
1909 where = entry;
1910 print_relr_addr_and_sym (filedata, symtab, nsyms, strtab, where);
1911 printf ("\n");
1912 where += relr_entsize;
1914 else
1916 bool first = true;
1917 int j;
1919 /* The least significant bit is ignored. */
1920 if (entry == 1)
1921 /* This can actually happen when the linker is allowed to shrink
1922 RELR sections. For more details see: https://reviews.llvm.org/D67164. */
1923 continue;
1924 else if (i == 0)
1925 warn (_("Unusual RELR bitmap - no previous entry to set the base address\n"));
1927 for (j = 0; entry >>= 1; j++)
1928 if ((entry & 1) == 1)
1930 uint64_t addr = where + (j * relr_entsize);
1932 if (first)
1934 print_relr_addr_and_sym (filedata, symtab, nsyms, strtab, addr);
1935 first = false;
1937 else
1939 printf (_("\n%*s "), relr_entsize == 4 ? 15 : 23, " ");
1940 print_relr_addr_and_sym (filedata, symtab, nsyms, strtab, addr);
1944 printf ("\n");
1945 where += num_bits_in_entry * relr_entsize;
1949 free (relrs);
1950 return true;
1953 /* Display the contents of the relocation data found at the specified
1954 offset. */
1956 static bool
1957 dump_relocations (Filedata * filedata,
1958 uint64_t rel_offset,
1959 uint64_t rel_size,
1960 Elf_Internal_Sym * symtab,
1961 uint64_t nsyms,
1962 char * strtab,
1963 uint64_t strtablen,
1964 relocation_type rel_type,
1965 bool is_dynsym)
1967 size_t i;
1968 Elf_Internal_Rela * rels;
1969 bool res = true;
1971 if (rel_type == reltype_unknown)
1972 rel_type = guess_is_rela (filedata->file_header.e_machine) ? reltype_rela : reltype_rel;
1974 if (rel_type == reltype_rela)
1976 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
1977 return false;
1979 else if (rel_type == reltype_rel)
1981 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
1982 return false;
1984 else if (rel_type == reltype_relr)
1986 /* This should have been handled by display_relocations(). */
1987 return false;
1990 if (is_32bit_elf)
1992 if (rel_type == reltype_rela)
1994 if (do_wide)
1995 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1996 else
1997 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1999 else
2001 if (do_wide)
2002 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
2003 else
2004 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
2007 else
2009 if (rel_type == reltype_rela)
2011 if (do_wide)
2012 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2013 else
2014 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
2016 else
2018 if (do_wide)
2019 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2020 else
2021 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
2025 for (i = 0; i < rel_size; i++)
2027 const char * rtype;
2028 uint64_t offset;
2029 uint64_t inf;
2030 uint64_t symtab_index;
2031 uint64_t type;
2033 offset = rels[i].r_offset;
2034 inf = rels[i].r_info;
2036 type = get_reloc_type (filedata, inf);
2037 symtab_index = get_reloc_symindex (inf);
2039 if (is_32bit_elf)
2041 printf ("%8.8lx %8.8lx ",
2042 (unsigned long) offset & 0xffffffff,
2043 (unsigned long) inf & 0xffffffff);
2045 else
2047 printf (do_wide
2048 ? "%16.16" PRIx64 " %16.16" PRIx64 " "
2049 : "%12.12" PRIx64 " %12.12" PRIx64 " ",
2050 offset, inf);
2053 switch (filedata->file_header.e_machine)
2055 default:
2056 rtype = NULL;
2057 break;
2059 case EM_AARCH64:
2060 rtype = elf_aarch64_reloc_type (type);
2061 break;
2063 case EM_M32R:
2064 case EM_CYGNUS_M32R:
2065 rtype = elf_m32r_reloc_type (type);
2066 break;
2068 case EM_386:
2069 case EM_IAMCU:
2070 rtype = elf_i386_reloc_type (type);
2071 break;
2073 case EM_68HC11:
2074 case EM_68HC12:
2075 rtype = elf_m68hc11_reloc_type (type);
2076 break;
2078 case EM_S12Z:
2079 rtype = elf_s12z_reloc_type (type);
2080 break;
2082 case EM_68K:
2083 rtype = elf_m68k_reloc_type (type);
2084 break;
2086 case EM_960:
2087 rtype = elf_i960_reloc_type (type);
2088 break;
2090 case EM_AVR:
2091 case EM_AVR_OLD:
2092 rtype = elf_avr_reloc_type (type);
2093 break;
2095 case EM_OLD_SPARCV9:
2096 case EM_SPARC32PLUS:
2097 case EM_SPARCV9:
2098 case EM_SPARC:
2099 rtype = elf_sparc_reloc_type (type);
2100 break;
2102 case EM_SPU:
2103 rtype = elf_spu_reloc_type (type);
2104 break;
2106 case EM_V800:
2107 rtype = v800_reloc_type (type);
2108 break;
2109 case EM_V850:
2110 case EM_CYGNUS_V850:
2111 rtype = v850_reloc_type (type);
2112 break;
2114 case EM_D10V:
2115 case EM_CYGNUS_D10V:
2116 rtype = elf_d10v_reloc_type (type);
2117 break;
2119 case EM_D30V:
2120 case EM_CYGNUS_D30V:
2121 rtype = elf_d30v_reloc_type (type);
2122 break;
2124 case EM_DLX:
2125 rtype = elf_dlx_reloc_type (type);
2126 break;
2128 case EM_SH:
2129 rtype = elf_sh_reloc_type (type);
2130 break;
2132 case EM_MN10300:
2133 case EM_CYGNUS_MN10300:
2134 rtype = elf_mn10300_reloc_type (type);
2135 break;
2137 case EM_MN10200:
2138 case EM_CYGNUS_MN10200:
2139 rtype = elf_mn10200_reloc_type (type);
2140 break;
2142 case EM_FR30:
2143 case EM_CYGNUS_FR30:
2144 rtype = elf_fr30_reloc_type (type);
2145 break;
2147 case EM_CYGNUS_FRV:
2148 rtype = elf_frv_reloc_type (type);
2149 break;
2151 case EM_CSKY:
2152 rtype = elf_csky_reloc_type (type);
2153 break;
2155 case EM_FT32:
2156 rtype = elf_ft32_reloc_type (type);
2157 break;
2159 case EM_MCORE:
2160 rtype = elf_mcore_reloc_type (type);
2161 break;
2163 case EM_MMIX:
2164 rtype = elf_mmix_reloc_type (type);
2165 break;
2167 case EM_MOXIE:
2168 rtype = elf_moxie_reloc_type (type);
2169 break;
2171 case EM_MSP430:
2172 if (uses_msp430x_relocs (filedata))
2174 rtype = elf_msp430x_reloc_type (type);
2175 break;
2177 /* Fall through. */
2178 case EM_MSP430_OLD:
2179 rtype = elf_msp430_reloc_type (type);
2180 break;
2182 case EM_NDS32:
2183 rtype = elf_nds32_reloc_type (type);
2184 break;
2186 case EM_PPC:
2187 rtype = elf_ppc_reloc_type (type);
2188 break;
2190 case EM_PPC64:
2191 rtype = elf_ppc64_reloc_type (type);
2192 break;
2194 case EM_MIPS:
2195 case EM_MIPS_RS3_LE:
2196 rtype = elf_mips_reloc_type (type);
2197 break;
2199 case EM_RISCV:
2200 rtype = elf_riscv_reloc_type (type);
2201 break;
2203 case EM_ALPHA:
2204 rtype = elf_alpha_reloc_type (type);
2205 break;
2207 case EM_ARM:
2208 rtype = elf_arm_reloc_type (type);
2209 break;
2211 case EM_ARC:
2212 case EM_ARC_COMPACT:
2213 case EM_ARC_COMPACT2:
2214 case EM_ARC_COMPACT3:
2215 case EM_ARC_COMPACT3_64:
2216 rtype = elf_arc_reloc_type (type);
2217 break;
2219 case EM_PARISC:
2220 rtype = elf_hppa_reloc_type (type);
2221 break;
2223 case EM_H8_300:
2224 case EM_H8_300H:
2225 case EM_H8S:
2226 rtype = elf_h8_reloc_type (type);
2227 break;
2229 case EM_OR1K:
2230 rtype = elf_or1k_reloc_type (type);
2231 break;
2233 case EM_PJ:
2234 case EM_PJ_OLD:
2235 rtype = elf_pj_reloc_type (type);
2236 break;
2237 case EM_IA_64:
2238 rtype = elf_ia64_reloc_type (type);
2239 break;
2241 case EM_KVX:
2242 rtype = elf_kvx_reloc_type (type);
2243 break;
2245 case EM_CRIS:
2246 rtype = elf_cris_reloc_type (type);
2247 break;
2249 case EM_860:
2250 rtype = elf_i860_reloc_type (type);
2251 break;
2253 case EM_X86_64:
2254 case EM_L1OM:
2255 case EM_K1OM:
2256 rtype = elf_x86_64_reloc_type (type);
2257 break;
2259 case EM_S370:
2260 rtype = i370_reloc_type (type);
2261 break;
2263 case EM_S390_OLD:
2264 case EM_S390:
2265 rtype = elf_s390_reloc_type (type);
2266 break;
2268 case EM_SCORE:
2269 rtype = elf_score_reloc_type (type);
2270 break;
2272 case EM_XSTORMY16:
2273 rtype = elf_xstormy16_reloc_type (type);
2274 break;
2276 case EM_CRX:
2277 rtype = elf_crx_reloc_type (type);
2278 break;
2280 case EM_VAX:
2281 rtype = elf_vax_reloc_type (type);
2282 break;
2284 case EM_VISIUM:
2285 rtype = elf_visium_reloc_type (type);
2286 break;
2288 case EM_BPF:
2289 rtype = elf_bpf_reloc_type (type);
2290 break;
2292 case EM_ADAPTEVA_EPIPHANY:
2293 rtype = elf_epiphany_reloc_type (type);
2294 break;
2296 case EM_IP2K:
2297 case EM_IP2K_OLD:
2298 rtype = elf_ip2k_reloc_type (type);
2299 break;
2301 case EM_IQ2000:
2302 rtype = elf_iq2000_reloc_type (type);
2303 break;
2305 case EM_XTENSA_OLD:
2306 case EM_XTENSA:
2307 rtype = elf_xtensa_reloc_type (type);
2308 break;
2310 case EM_LATTICEMICO32:
2311 rtype = elf_lm32_reloc_type (type);
2312 break;
2314 case EM_M32C_OLD:
2315 case EM_M32C:
2316 rtype = elf_m32c_reloc_type (type);
2317 break;
2319 case EM_MT:
2320 rtype = elf_mt_reloc_type (type);
2321 break;
2323 case EM_BLACKFIN:
2324 rtype = elf_bfin_reloc_type (type);
2325 break;
2327 case EM_CYGNUS_MEP:
2328 rtype = elf_mep_reloc_type (type);
2329 break;
2331 case EM_CR16:
2332 rtype = elf_cr16_reloc_type (type);
2333 break;
2335 case EM_MICROBLAZE:
2336 case EM_MICROBLAZE_OLD:
2337 rtype = elf_microblaze_reloc_type (type);
2338 break;
2340 case EM_RL78:
2341 rtype = elf_rl78_reloc_type (type);
2342 break;
2344 case EM_RX:
2345 rtype = elf_rx_reloc_type (type);
2346 break;
2348 case EM_METAG:
2349 rtype = elf_metag_reloc_type (type);
2350 break;
2352 case EM_TI_C6000:
2353 rtype = elf_tic6x_reloc_type (type);
2354 break;
2356 case EM_TILEGX:
2357 rtype = elf_tilegx_reloc_type (type);
2358 break;
2360 case EM_TILEPRO:
2361 rtype = elf_tilepro_reloc_type (type);
2362 break;
2364 case EM_WEBASSEMBLY:
2365 rtype = elf_wasm32_reloc_type (type);
2366 break;
2368 case EM_XGATE:
2369 rtype = elf_xgate_reloc_type (type);
2370 break;
2372 case EM_ALTERA_NIOS2:
2373 rtype = elf_nios2_reloc_type (type);
2374 break;
2376 case EM_TI_PRU:
2377 rtype = elf_pru_reloc_type (type);
2378 break;
2380 case EM_NFP:
2381 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
2382 rtype = elf_nfp3200_reloc_type (type);
2383 else
2384 rtype = elf_nfp_reloc_type (type);
2385 break;
2387 case EM_Z80:
2388 rtype = elf_z80_reloc_type (type);
2389 break;
2391 case EM_LOONGARCH:
2392 rtype = elf_loongarch_reloc_type (type);
2393 break;
2395 case EM_AMDGPU:
2396 rtype = elf_amdgpu_reloc_type (type);
2397 break;
2400 if (rtype == NULL)
2401 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
2402 else
2403 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
2405 if (filedata->file_header.e_machine == EM_ALPHA
2406 && rtype != NULL
2407 && streq (rtype, "R_ALPHA_LITUSE")
2408 && rel_type == reltype_rela)
2410 switch (rels[i].r_addend)
2412 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
2413 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
2414 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
2415 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
2416 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
2417 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
2418 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
2419 default: rtype = NULL;
2422 if (rtype)
2423 printf (" (%s)", rtype);
2424 else
2426 putchar (' ');
2427 printf (_("<unknown addend: %" PRIx64 ">"),
2428 rels[i].r_addend);
2429 res = false;
2432 else if (symtab_index)
2434 if (symtab == NULL || symtab_index >= nsyms)
2436 error (_(" bad symbol index: %08lx in reloc\n"),
2437 (unsigned long) symtab_index);
2438 res = false;
2440 else
2442 Elf_Internal_Sym * psym;
2443 const char * version_string;
2444 enum versioned_symbol_info sym_info;
2445 unsigned short vna_other;
2447 psym = symtab + symtab_index;
2449 version_string
2450 = get_symbol_version_string (filedata, is_dynsym,
2451 strtab, strtablen,
2452 symtab_index,
2453 psym,
2454 &sym_info,
2455 &vna_other);
2457 printf (" ");
2459 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
2461 const char * name;
2462 unsigned int len;
2463 unsigned int width = is_32bit_elf ? 8 : 14;
2465 /* Relocations against GNU_IFUNC symbols do not use the value
2466 of the symbol as the address to relocate against. Instead
2467 they invoke the function named by the symbol and use its
2468 result as the address for relocation.
2470 To indicate this to the user, do not display the value of
2471 the symbol in the "Symbols's Value" field. Instead show
2472 its name followed by () as a hint that the symbol is
2473 invoked. */
2475 if (strtab == NULL
2476 || psym->st_name == 0
2477 || psym->st_name >= strtablen)
2478 name = "??";
2479 else
2480 name = strtab + psym->st_name;
2482 len = print_symbol_name (width, name);
2483 if (version_string)
2484 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2485 version_string);
2486 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
2488 else
2490 print_vma (psym->st_value, LONG_HEX);
2492 printf (is_32bit_elf ? " " : " ");
2495 if (psym->st_name == 0)
2497 const char * sec_name = "<null>";
2499 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
2500 sec_name = printable_section_name_from_index
2501 (filedata, psym->st_shndx, NULL);
2503 print_symbol_name (22, sec_name);
2505 else if (strtab == NULL)
2506 printf (_("<string table index: %3ld>"), psym->st_name);
2507 else if (psym->st_name >= strtablen)
2509 error (_("<corrupt string table index: %3ld>\n"),
2510 psym->st_name);
2511 res = false;
2513 else
2515 print_symbol_name (22, strtab + psym->st_name);
2516 if (version_string)
2517 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2518 version_string);
2521 if (rel_type == reltype_rela)
2523 uint64_t off = rels[i].r_addend;
2525 if ((int64_t) off < 0)
2526 printf (" - %" PRIx64, -off);
2527 else
2528 printf (" + %" PRIx64, off);
2532 else if (rel_type == reltype_rela)
2534 uint64_t off = rels[i].r_addend;
2536 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
2537 if ((int64_t) off < 0)
2538 printf ("-%" PRIx64, -off);
2539 else
2540 printf ("%" PRIx64, off);
2543 if (filedata->file_header.e_machine == EM_SPARCV9
2544 && rtype != NULL
2545 && streq (rtype, "R_SPARC_OLO10"))
2546 printf (" + %" PRIx64, ELF64_R_TYPE_DATA (inf));
2548 putchar ('\n');
2550 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2552 uint64_t type2 = ELF64_MIPS_R_TYPE2 (inf);
2553 uint64_t type3 = ELF64_MIPS_R_TYPE3 (inf);
2554 const char * rtype2 = elf_mips_reloc_type (type2);
2555 const char * rtype3 = elf_mips_reloc_type (type3);
2557 printf (" Type2: ");
2559 if (rtype2 == NULL)
2560 printf (_("unrecognized: %-7lx"),
2561 (unsigned long) type2 & 0xffffffff);
2562 else
2563 printf ("%-17.17s", rtype2);
2565 printf ("\n Type3: ");
2567 if (rtype3 == NULL)
2568 printf (_("unrecognized: %-7lx"),
2569 (unsigned long) type3 & 0xffffffff);
2570 else
2571 printf ("%-17.17s", rtype3);
2573 putchar ('\n');
2577 free (rels);
2579 return res;
2582 static const char *
2583 get_aarch64_dynamic_type (unsigned long type)
2585 switch (type)
2587 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
2588 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2589 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
2590 default:
2591 return NULL;
2595 static const char *
2596 get_mips_dynamic_type (unsigned long type)
2598 switch (type)
2600 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
2601 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
2602 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
2603 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
2604 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
2605 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
2606 case DT_MIPS_MSYM: return "MIPS_MSYM";
2607 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2608 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2609 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
2610 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
2611 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
2612 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
2613 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
2614 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
2615 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
2616 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
2617 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
2618 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
2619 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
2620 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
2621 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
2622 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
2623 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
2624 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
2625 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
2626 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
2627 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
2628 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
2629 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
2630 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2631 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
2632 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
2633 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
2634 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
2635 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2636 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
2637 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
2638 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
2639 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
2640 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
2641 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
2642 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
2643 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
2644 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
2645 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
2646 case DT_MIPS_XHASH: return "MIPS_XHASH";
2647 default:
2648 return NULL;
2652 static const char *
2653 get_sparc64_dynamic_type (unsigned long type)
2655 switch (type)
2657 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
2658 default:
2659 return NULL;
2663 static const char *
2664 get_ppc_dynamic_type (unsigned long type)
2666 switch (type)
2668 case DT_PPC_GOT: return "PPC_GOT";
2669 case DT_PPC_OPT: return "PPC_OPT";
2670 default:
2671 return NULL;
2675 static const char *
2676 get_ppc64_dynamic_type (unsigned long type)
2678 switch (type)
2680 case DT_PPC64_GLINK: return "PPC64_GLINK";
2681 case DT_PPC64_OPD: return "PPC64_OPD";
2682 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
2683 case DT_PPC64_OPT: return "PPC64_OPT";
2684 default:
2685 return NULL;
2689 static const char *
2690 get_parisc_dynamic_type (unsigned long type)
2692 switch (type)
2694 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
2695 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
2696 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
2697 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
2698 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
2699 case DT_HP_PREINIT: return "HP_PREINIT";
2700 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
2701 case DT_HP_NEEDED: return "HP_NEEDED";
2702 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
2703 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2704 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2705 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2706 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
2707 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2708 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2709 case DT_HP_FILTERED: return "HP_FILTERED";
2710 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2711 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2712 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2713 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2714 case DT_PLT: return "PLT";
2715 case DT_PLT_SIZE: return "PLT_SIZE";
2716 case DT_DLT: return "DLT";
2717 case DT_DLT_SIZE: return "DLT_SIZE";
2718 default:
2719 return NULL;
2723 static const char *
2724 get_ia64_dynamic_type (unsigned long type)
2726 switch (type)
2728 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2729 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2730 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2731 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2732 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2733 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2734 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2735 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2736 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2737 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2738 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2739 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2740 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2741 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2742 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2743 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2744 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2745 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2746 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2747 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2748 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2749 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2750 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2751 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2752 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2753 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2754 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2755 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2756 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2757 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2758 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
2759 default:
2760 return NULL;
2764 static const char *
2765 get_solaris_section_type (unsigned long type)
2767 switch (type)
2769 case 0x6fffffee: return "SUNW_ancillary";
2770 case 0x6fffffef: return "SUNW_capchain";
2771 case 0x6ffffff0: return "SUNW_capinfo";
2772 case 0x6ffffff1: return "SUNW_symsort";
2773 case 0x6ffffff2: return "SUNW_tlssort";
2774 case 0x6ffffff3: return "SUNW_LDYNSYM";
2775 case 0x6ffffff4: return "SUNW_dof";
2776 case 0x6ffffff5: return "SUNW_cap";
2777 case 0x6ffffff6: return "SUNW_SIGNATURE";
2778 case 0x6ffffff7: return "SUNW_ANNOTATE";
2779 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2780 case 0x6ffffff9: return "SUNW_DEBUG";
2781 case 0x6ffffffa: return "SUNW_move";
2782 case 0x6ffffffb: return "SUNW_COMDAT";
2783 case 0x6ffffffc: return "SUNW_syminfo";
2784 case 0x6ffffffd: return "SUNW_verdef";
2785 case 0x6ffffffe: return "SUNW_verneed";
2786 case 0x6fffffff: return "SUNW_versym";
2787 case 0x70000000: return "SPARC_GOTDATA";
2788 default: return NULL;
2792 static const char *
2793 get_alpha_dynamic_type (unsigned long type)
2795 switch (type)
2797 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
2798 default: return NULL;
2802 static const char *
2803 get_score_dynamic_type (unsigned long type)
2805 switch (type)
2807 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2808 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2809 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2810 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2811 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2812 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
2813 default: return NULL;
2817 static const char *
2818 get_tic6x_dynamic_type (unsigned long type)
2820 switch (type)
2822 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2823 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2824 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2825 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2826 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2827 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
2828 default: return NULL;
2832 static const char *
2833 get_nios2_dynamic_type (unsigned long type)
2835 switch (type)
2837 case DT_NIOS2_GP: return "NIOS2_GP";
2838 default: return NULL;
2842 static const char *
2843 get_solaris_dynamic_type (unsigned long type)
2845 switch (type)
2847 case 0x6000000d: return "SUNW_AUXILIARY";
2848 case 0x6000000e: return "SUNW_RTLDINF";
2849 case 0x6000000f: return "SUNW_FILTER";
2850 case 0x60000010: return "SUNW_CAP";
2851 case 0x60000011: return "SUNW_SYMTAB";
2852 case 0x60000012: return "SUNW_SYMSZ";
2853 case 0x60000013: return "SUNW_SORTENT";
2854 case 0x60000014: return "SUNW_SYMSORT";
2855 case 0x60000015: return "SUNW_SYMSORTSZ";
2856 case 0x60000016: return "SUNW_TLSSORT";
2857 case 0x60000017: return "SUNW_TLSSORTSZ";
2858 case 0x60000018: return "SUNW_CAPINFO";
2859 case 0x60000019: return "SUNW_STRPAD";
2860 case 0x6000001a: return "SUNW_CAPCHAIN";
2861 case 0x6000001b: return "SUNW_LDMACH";
2862 case 0x6000001d: return "SUNW_CAPCHAINENT";
2863 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2864 case 0x60000021: return "SUNW_PARENT";
2865 case 0x60000023: return "SUNW_ASLR";
2866 case 0x60000025: return "SUNW_RELAX";
2867 case 0x60000029: return "SUNW_NXHEAP";
2868 case 0x6000002b: return "SUNW_NXSTACK";
2870 case 0x70000001: return "SPARC_REGISTER";
2871 case 0x7ffffffd: return "AUXILIARY";
2872 case 0x7ffffffe: return "USED";
2873 case 0x7fffffff: return "FILTER";
2875 default: return NULL;
2879 static const char *
2880 get_riscv_dynamic_type (unsigned long type)
2882 switch (type)
2884 case DT_RISCV_VARIANT_CC: return "RISCV_VARIANT_CC";
2885 default:
2886 return NULL;
2890 static const char *
2891 get_x86_64_dynamic_type (unsigned long type)
2893 switch (type)
2895 case DT_X86_64_PLT:
2896 return "DT_X86_64_PLT";
2897 case DT_X86_64_PLTSZ:
2898 return "DT_X86_64_PLTSZ";
2899 case DT_X86_64_PLTENT:
2900 return "DT_X86_64_PLTENT";
2901 default:
2902 return NULL;
2906 static const char *
2907 get_dynamic_type (Filedata * filedata, unsigned long type)
2909 static char buff[64];
2911 switch (type)
2913 case DT_NULL: return "NULL";
2914 case DT_NEEDED: return "NEEDED";
2915 case DT_PLTRELSZ: return "PLTRELSZ";
2916 case DT_PLTGOT: return "PLTGOT";
2917 case DT_HASH: return "HASH";
2918 case DT_STRTAB: return "STRTAB";
2919 case DT_SYMTAB: return "SYMTAB";
2920 case DT_RELA: return "RELA";
2921 case DT_RELASZ: return "RELASZ";
2922 case DT_RELAENT: return "RELAENT";
2923 case DT_STRSZ: return "STRSZ";
2924 case DT_SYMENT: return "SYMENT";
2925 case DT_INIT: return "INIT";
2926 case DT_FINI: return "FINI";
2927 case DT_SONAME: return "SONAME";
2928 case DT_RPATH: return "RPATH";
2929 case DT_SYMBOLIC: return "SYMBOLIC";
2930 case DT_REL: return "REL";
2931 case DT_RELSZ: return "RELSZ";
2932 case DT_RELENT: return "RELENT";
2933 case DT_RELR: return "RELR";
2934 case DT_RELRSZ: return "RELRSZ";
2935 case DT_RELRENT: return "RELRENT";
2936 case DT_PLTREL: return "PLTREL";
2937 case DT_DEBUG: return "DEBUG";
2938 case DT_TEXTREL: return "TEXTREL";
2939 case DT_JMPREL: return "JMPREL";
2940 case DT_BIND_NOW: return "BIND_NOW";
2941 case DT_INIT_ARRAY: return "INIT_ARRAY";
2942 case DT_FINI_ARRAY: return "FINI_ARRAY";
2943 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2944 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
2945 case DT_RUNPATH: return "RUNPATH";
2946 case DT_FLAGS: return "FLAGS";
2948 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2949 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
2950 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
2952 case DT_CHECKSUM: return "CHECKSUM";
2953 case DT_PLTPADSZ: return "PLTPADSZ";
2954 case DT_MOVEENT: return "MOVEENT";
2955 case DT_MOVESZ: return "MOVESZ";
2956 case DT_FEATURE: return "FEATURE";
2957 case DT_POSFLAG_1: return "POSFLAG_1";
2958 case DT_SYMINSZ: return "SYMINSZ";
2959 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
2961 case DT_ADDRRNGLO: return "ADDRRNGLO";
2962 case DT_CONFIG: return "CONFIG";
2963 case DT_DEPAUDIT: return "DEPAUDIT";
2964 case DT_AUDIT: return "AUDIT";
2965 case DT_PLTPAD: return "PLTPAD";
2966 case DT_MOVETAB: return "MOVETAB";
2967 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
2969 case DT_VERSYM: return "VERSYM";
2971 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2972 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
2973 case DT_RELACOUNT: return "RELACOUNT";
2974 case DT_RELCOUNT: return "RELCOUNT";
2975 case DT_FLAGS_1: return "FLAGS_1";
2976 case DT_VERDEF: return "VERDEF";
2977 case DT_VERDEFNUM: return "VERDEFNUM";
2978 case DT_VERNEED: return "VERNEED";
2979 case DT_VERNEEDNUM: return "VERNEEDNUM";
2981 case DT_AUXILIARY: return "AUXILIARY";
2982 case DT_USED: return "USED";
2983 case DT_FILTER: return "FILTER";
2985 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2986 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2987 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2988 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2989 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
2990 case DT_GNU_HASH: return "GNU_HASH";
2991 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
2993 default:
2994 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2996 const char * result;
2998 switch (filedata->file_header.e_machine)
3000 case EM_AARCH64:
3001 result = get_aarch64_dynamic_type (type);
3002 break;
3003 case EM_MIPS:
3004 case EM_MIPS_RS3_LE:
3005 result = get_mips_dynamic_type (type);
3006 break;
3007 case EM_SPARCV9:
3008 result = get_sparc64_dynamic_type (type);
3009 break;
3010 case EM_PPC:
3011 result = get_ppc_dynamic_type (type);
3012 break;
3013 case EM_PPC64:
3014 result = get_ppc64_dynamic_type (type);
3015 break;
3016 case EM_IA_64:
3017 result = get_ia64_dynamic_type (type);
3018 break;
3019 case EM_ALPHA:
3020 result = get_alpha_dynamic_type (type);
3021 break;
3022 case EM_SCORE:
3023 result = get_score_dynamic_type (type);
3024 break;
3025 case EM_TI_C6000:
3026 result = get_tic6x_dynamic_type (type);
3027 break;
3028 case EM_ALTERA_NIOS2:
3029 result = get_nios2_dynamic_type (type);
3030 break;
3031 case EM_RISCV:
3032 result = get_riscv_dynamic_type (type);
3033 break;
3034 case EM_X86_64:
3035 result = get_x86_64_dynamic_type (type);
3036 break;
3037 default:
3038 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
3039 result = get_solaris_dynamic_type (type);
3040 else
3041 result = NULL;
3042 break;
3045 if (result != NULL)
3046 return result;
3048 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
3050 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
3051 || (filedata->file_header.e_machine == EM_PARISC
3052 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
3054 const char * result;
3056 switch (filedata->file_header.e_machine)
3058 case EM_PARISC:
3059 result = get_parisc_dynamic_type (type);
3060 break;
3061 case EM_IA_64:
3062 result = get_ia64_dynamic_type (type);
3063 break;
3064 default:
3065 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
3066 result = get_solaris_dynamic_type (type);
3067 else
3068 result = NULL;
3069 break;
3072 if (result != NULL)
3073 return result;
3075 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
3076 type);
3078 else
3079 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
3081 return buff;
3085 static bool get_program_headers (Filedata *);
3086 static bool get_dynamic_section (Filedata *);
3088 static void
3089 locate_dynamic_section (Filedata *filedata)
3091 uint64_t dynamic_addr = 0;
3092 uint64_t dynamic_size = 0;
3094 if (filedata->file_header.e_phnum != 0
3095 && get_program_headers (filedata))
3097 Elf_Internal_Phdr *segment;
3098 unsigned int i;
3100 for (i = 0, segment = filedata->program_headers;
3101 i < filedata->file_header.e_phnum;
3102 i++, segment++)
3104 if (segment->p_type == PT_DYNAMIC)
3106 dynamic_addr = segment->p_offset;
3107 dynamic_size = segment->p_filesz;
3109 if (filedata->section_headers != NULL)
3111 Elf_Internal_Shdr *sec;
3113 sec = find_section (filedata, ".dynamic");
3114 if (sec != NULL)
3116 if (sec->sh_size == 0
3117 || sec->sh_type == SHT_NOBITS)
3119 dynamic_addr = 0;
3120 dynamic_size = 0;
3122 else
3124 dynamic_addr = sec->sh_offset;
3125 dynamic_size = sec->sh_size;
3130 if (dynamic_addr > filedata->file_size
3131 || (dynamic_size > filedata->file_size - dynamic_addr))
3133 dynamic_addr = 0;
3134 dynamic_size = 0;
3136 break;
3140 filedata->dynamic_addr = dynamic_addr;
3141 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
3144 static bool
3145 is_pie (Filedata *filedata)
3147 Elf_Internal_Dyn *entry;
3149 if (filedata->dynamic_size == 0)
3150 locate_dynamic_section (filedata);
3151 if (filedata->dynamic_size <= 1)
3152 return false;
3154 if (!get_dynamic_section (filedata))
3155 return false;
3157 for (entry = filedata->dynamic_section;
3158 entry < filedata->dynamic_section + filedata->dynamic_nent;
3159 entry++)
3161 if (entry->d_tag == DT_FLAGS_1)
3163 if ((entry->d_un.d_val & DF_1_PIE) != 0)
3164 return true;
3165 break;
3168 return false;
3171 static char *
3172 get_file_type (Filedata *filedata)
3174 unsigned e_type = filedata->file_header.e_type;
3175 static char buff[64];
3177 switch (e_type)
3179 case ET_NONE: return _("NONE (None)");
3180 case ET_REL: return _("REL (Relocatable file)");
3181 case ET_EXEC: return _("EXEC (Executable file)");
3182 case ET_DYN:
3183 if (is_pie (filedata))
3184 return _("DYN (Position-Independent Executable file)");
3185 else
3186 return _("DYN (Shared object file)");
3187 case ET_CORE: return _("CORE (Core file)");
3189 default:
3190 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
3191 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
3192 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
3193 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
3194 else
3195 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
3196 return buff;
3200 static char *
3201 get_machine_name (unsigned e_machine)
3203 static char buff[64]; /* XXX */
3205 switch (e_machine)
3207 /* Please keep this switch table sorted by increasing EM_ value. */
3208 /* 0 */
3209 case EM_NONE: return _("None");
3210 case EM_M32: return "WE32100";
3211 case EM_SPARC: return "Sparc";
3212 case EM_386: return "Intel 80386";
3213 case EM_68K: return "MC68000";
3214 case EM_88K: return "MC88000";
3215 case EM_IAMCU: return "Intel MCU";
3216 case EM_860: return "Intel 80860";
3217 case EM_MIPS: return "MIPS R3000";
3218 case EM_S370: return "IBM System/370";
3219 /* 10 */
3220 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
3221 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
3222 case EM_PARISC: return "HPPA";
3223 case EM_VPP550: return "Fujitsu VPP500";
3224 case EM_SPARC32PLUS: return "Sparc v8+" ;
3225 case EM_960: return "Intel 80960";
3226 case EM_PPC: return "PowerPC";
3227 /* 20 */
3228 case EM_PPC64: return "PowerPC64";
3229 case EM_S390_OLD:
3230 case EM_S390: return "IBM S/390";
3231 case EM_SPU: return "SPU";
3232 /* 30 */
3233 case EM_V800: return "Renesas V850 (using RH850 ABI)";
3234 case EM_FR20: return "Fujitsu FR20";
3235 case EM_RH32: return "TRW RH32";
3236 case EM_MCORE: return "MCORE";
3237 /* 40 */
3238 case EM_ARM: return "ARM";
3239 case EM_OLD_ALPHA: return "Digital Alpha (old)";
3240 case EM_SH: return "Renesas / SuperH SH";
3241 case EM_SPARCV9: return "Sparc v9";
3242 case EM_TRICORE: return "Siemens Tricore";
3243 case EM_ARC: return "ARC";
3244 case EM_H8_300: return "Renesas H8/300";
3245 case EM_H8_300H: return "Renesas H8/300H";
3246 case EM_H8S: return "Renesas H8S";
3247 case EM_H8_500: return "Renesas H8/500";
3248 /* 50 */
3249 case EM_IA_64: return "Intel IA-64";
3250 case EM_MIPS_X: return "Stanford MIPS-X";
3251 case EM_COLDFIRE: return "Motorola Coldfire";
3252 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
3253 case EM_MMA: return "Fujitsu Multimedia Accelerator";
3254 case EM_PCP: return "Siemens PCP";
3255 case EM_NCPU: return "Sony nCPU embedded RISC processor";
3256 case EM_NDR1: return "Denso NDR1 microprocessor";
3257 case EM_STARCORE: return "Motorola Star*Core processor";
3258 case EM_ME16: return "Toyota ME16 processor";
3259 /* 60 */
3260 case EM_ST100: return "STMicroelectronics ST100 processor";
3261 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
3262 case EM_X86_64: return "Advanced Micro Devices X86-64";
3263 case EM_PDSP: return "Sony DSP processor";
3264 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
3265 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
3266 case EM_FX66: return "Siemens FX66 microcontroller";
3267 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
3268 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
3269 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
3270 /* 70 */
3271 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
3272 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
3273 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
3274 case EM_SVX: return "Silicon Graphics SVx";
3275 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
3276 case EM_VAX: return "Digital VAX";
3277 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
3278 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
3279 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
3280 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
3281 /* 80 */
3282 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
3283 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3284 case EM_PRISM: return "Vitesse Prism";
3285 case EM_AVR_OLD:
3286 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
3287 case EM_CYGNUS_FR30:
3288 case EM_FR30: return "Fujitsu FR30";
3289 case EM_CYGNUS_D10V:
3290 case EM_D10V: return "d10v";
3291 case EM_CYGNUS_D30V:
3292 case EM_D30V: return "d30v";
3293 case EM_CYGNUS_V850:
3294 case EM_V850: return "Renesas V850";
3295 case EM_CYGNUS_M32R:
3296 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
3297 case EM_CYGNUS_MN10300:
3298 case EM_MN10300: return "mn10300";
3299 /* 90 */
3300 case EM_CYGNUS_MN10200:
3301 case EM_MN10200: return "mn10200";
3302 case EM_PJ: return "picoJava";
3303 case EM_OR1K: return "OpenRISC 1000";
3304 case EM_ARC_COMPACT: return "ARCompact";
3305 case EM_XTENSA_OLD:
3306 case EM_XTENSA: return "Tensilica Xtensa Processor";
3307 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
3308 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
3309 case EM_NS32K: return "National Semiconductor 32000 series";
3310 case EM_TPC: return "Tenor Network TPC processor";
3311 case EM_SNP1K: return "Trebia SNP 1000 processor";
3312 /* 100 */
3313 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
3314 case EM_IP2K_OLD:
3315 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3316 case EM_MAX: return "MAX Processor";
3317 case EM_CR: return "National Semiconductor CompactRISC";
3318 case EM_F2MC16: return "Fujitsu F2MC16";
3319 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
3320 case EM_BLACKFIN: return "Analog Devices Blackfin";
3321 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
3322 case EM_SEP: return "Sharp embedded microprocessor";
3323 case EM_ARCA: return "Arca RISC microprocessor";
3324 /* 110 */
3325 case EM_UNICORE: return "Unicore";
3326 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
3327 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
3328 case EM_ALTERA_NIOS2: return "Altera Nios II";
3329 case EM_CRX: return "National Semiconductor CRX microprocessor";
3330 case EM_XGATE: return "Motorola XGATE embedded processor";
3331 case EM_C166:
3332 case EM_XC16X: return "Infineon Technologies xc16x";
3333 case EM_M16C: return "Renesas M16C series microprocessors";
3334 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
3335 case EM_CE: return "Freescale Communication Engine RISC core";
3336 /* 120 */
3337 case EM_M32C: return "Renesas M32c";
3338 /* 130 */
3339 case EM_TSK3000: return "Altium TSK3000 core";
3340 case EM_RS08: return "Freescale RS08 embedded processor";
3341 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
3342 case EM_SCORE: return "SUNPLUS S+Core";
3343 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
3344 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
3345 case EM_LATTICEMICO32: return "Lattice Mico32";
3346 case EM_SE_C17: return "Seiko Epson C17 family";
3347 /* 140 */
3348 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
3349 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
3350 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
3351 case EM_TI_PRU: return "TI PRU I/O processor";
3352 /* 160 */
3353 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
3354 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
3355 case EM_R32C: return "Renesas R32C series microprocessors";
3356 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
3357 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
3358 case EM_8051: return "Intel 8051 and variants";
3359 case EM_STXP7X: return "STMicroelectronics STxP7x family";
3360 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
3361 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
3362 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
3363 /* 170 */
3364 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
3365 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
3366 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
3367 case EM_RX: return "Renesas RX";
3368 case EM_METAG: return "Imagination Technologies Meta processor architecture";
3369 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
3370 case EM_ECOG16: return "Cyan Technology eCOG16 family";
3371 case EM_CR16:
3372 case EM_MICROBLAZE:
3373 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
3374 case EM_ETPU: return "Freescale Extended Time Processing Unit";
3375 case EM_SLE9X: return "Infineon Technologies SLE9X core";
3376 /* 180 */
3377 case EM_L1OM: return "Intel L1OM";
3378 case EM_K1OM: return "Intel K1OM";
3379 case EM_INTEL182: return "Intel (reserved)";
3380 case EM_AARCH64: return "AArch64";
3381 case EM_ARM184: return "ARM (reserved)";
3382 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
3383 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
3384 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
3385 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
3386 /* 190 */
3387 case EM_CUDA: return "NVIDIA CUDA architecture";
3388 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
3389 case EM_CLOUDSHIELD: return "CloudShield architecture family";
3390 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
3391 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
3392 case EM_ARC_COMPACT2: return "ARCv2";
3393 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
3394 case EM_RL78: return "Renesas RL78";
3395 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
3396 case EM_78K0R: return "Renesas 78K0R";
3397 /* 200 */
3398 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
3399 case EM_BA1: return "Beyond BA1 CPU architecture";
3400 case EM_BA2: return "Beyond BA2 CPU architecture";
3401 case EM_XCORE: return "XMOS xCORE processor family";
3402 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
3403 case EM_INTELGT: return "Intel Graphics Technology";
3404 /* 210 */
3405 case EM_KM32: return "KM211 KM32 32-bit processor";
3406 case EM_KMX32: return "KM211 KMX32 32-bit processor";
3407 case EM_KMX16: return "KM211 KMX16 16-bit processor";
3408 case EM_KMX8: return "KM211 KMX8 8-bit processor";
3409 case EM_KVARC: return "KM211 KVARC processor";
3410 case EM_CDP: return "Paneve CDP architecture family";
3411 case EM_COGE: return "Cognitive Smart Memory Processor";
3412 case EM_COOL: return "Bluechip Systems CoolEngine";
3413 case EM_NORC: return "Nanoradio Optimized RISC";
3414 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
3415 /* 220 */
3416 case EM_Z80: return "Zilog Z80";
3417 case EM_VISIUM: return "CDS VISIUMcore processor";
3418 case EM_FT32: return "FTDI Chip FT32";
3419 case EM_MOXIE: return "Moxie";
3420 case EM_AMDGPU: return "AMD GPU";
3421 /* 230 (all reserved) */
3422 /* 240 */
3423 case EM_RISCV: return "RISC-V";
3424 case EM_LANAI: return "Lanai 32-bit processor";
3425 case EM_CEVA: return "CEVA Processor Architecture Family";
3426 case EM_CEVA_X2: return "CEVA X2 Processor Family";
3427 case EM_BPF: return "Linux BPF";
3428 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
3429 case EM_IMG1: return "Imagination Technologies";
3430 /* 250 */
3431 case EM_NFP: return "Netronome Flow Processor";
3432 case EM_VE: return "NEC Vector Engine";
3433 case EM_CSKY: return "C-SKY";
3434 case EM_ARC_COMPACT3_64: return "Synopsys ARCv3 64-bit processor";
3435 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
3436 case EM_ARC_COMPACT3: return "Synopsys ARCv3 32-bit processor";
3437 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
3438 case EM_65816: return "WDC 65816/65C816";
3439 case EM_LOONGARCH: return "LoongArch";
3440 case EM_KF32: return "ChipON KungFu32";
3442 /* Large numbers... */
3443 case EM_MT: return "Morpho Techologies MT processor";
3444 case EM_ALPHA: return "Alpha";
3445 case EM_WEBASSEMBLY: return "Web Assembly";
3446 case EM_DLX: return "OpenDLX";
3447 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3448 case EM_IQ2000: return "Vitesse IQ2000";
3449 case EM_M32C_OLD:
3450 case EM_NIOS32: return "Altera Nios";
3451 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
3452 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
3453 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
3454 case EM_S12Z: return "Freescale S12Z";
3456 default:
3457 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
3458 return buff;
3462 static char *
3463 decode_ARC_machine_flags (char *out, unsigned e_flags, unsigned e_machine)
3465 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
3466 other compilers don't specify an architecture type in the e_flags, and
3467 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
3468 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
3469 architectures.
3471 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
3472 but also sets a specific architecture type in the e_flags field.
3474 However, when decoding the flags we don't worry if we see an
3475 unexpected pairing, for example EM_ARC_COMPACT machine type, with
3476 ARCEM architecture type. */
3478 switch (e_flags & EF_ARC_MACH_MSK)
3480 /* We only expect these to occur for EM_ARC_COMPACT2. */
3481 case EF_ARC_CPU_ARCV2EM:
3482 out = stpcpy (out, ", ARC EM");
3483 break;
3484 case EF_ARC_CPU_ARCV2HS:
3485 out = stpcpy (out, ", ARC HS");
3486 break;
3488 /* We only expect these to occur for EM_ARC_COMPACT. */
3489 case E_ARC_MACH_ARC600:
3490 out = stpcpy (out, ", ARC600");
3491 break;
3492 case E_ARC_MACH_ARC601:
3493 out = stpcpy (out, ", ARC601");
3494 break;
3495 case E_ARC_MACH_ARC700:
3496 out = stpcpy (out, ", ARC700");
3497 break;
3499 /* The only times we should end up here are (a) A corrupt ELF, (b) A
3500 new ELF with new architecture being read by an old version of
3501 readelf, or (c) An ELF built with non-GNU compiler that does not
3502 set the architecture in the e_flags. */
3503 default:
3504 if (e_machine == EM_ARC_COMPACT)
3505 out = stpcpy (out, ", Unknown ARCompact");
3506 else
3507 out = stpcpy (out, ", Unknown ARC");
3508 break;
3511 switch (e_flags & EF_ARC_OSABI_MSK)
3513 case E_ARC_OSABI_ORIG:
3514 out = stpcpy (out, ", (ABI:legacy)");
3515 break;
3516 case E_ARC_OSABI_V2:
3517 out = stpcpy (out, ", (ABI:v2)");
3518 break;
3519 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3520 case E_ARC_OSABI_V3:
3521 out = stpcpy (out, ", v3 no-legacy-syscalls ABI");
3522 break;
3523 case E_ARC_OSABI_V4:
3524 out = stpcpy (out, ", v4 ABI");
3525 break;
3526 default:
3527 out = stpcpy (out, ", unrecognised ARC OSABI flag");
3528 break;
3530 return out;
3533 static char *
3534 decode_ARM_machine_flags (char *out, unsigned e_flags)
3536 unsigned eabi;
3537 bool unknown = false;
3539 eabi = EF_ARM_EABI_VERSION (e_flags);
3540 e_flags &= ~ EF_ARM_EABIMASK;
3542 /* Handle "generic" ARM flags. */
3543 if (e_flags & EF_ARM_RELEXEC)
3545 out = stpcpy (out, ", relocatable executable");
3546 e_flags &= ~ EF_ARM_RELEXEC;
3549 if (e_flags & EF_ARM_PIC)
3551 out = stpcpy (out, ", position independent");
3552 e_flags &= ~ EF_ARM_PIC;
3555 /* Now handle EABI specific flags. */
3556 switch (eabi)
3558 default:
3559 out = stpcpy (out, ", <unrecognized EABI>");
3560 if (e_flags)
3561 unknown = true;
3562 break;
3564 case EF_ARM_EABI_VER1:
3565 out = stpcpy (out, ", Version1 EABI");
3566 while (e_flags)
3568 unsigned flag;
3570 /* Process flags one bit at a time. */
3571 flag = e_flags & - e_flags;
3572 e_flags &= ~ flag;
3574 switch (flag)
3576 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
3577 out = stpcpy (out, ", sorted symbol tables");
3578 break;
3580 default:
3581 unknown = true;
3582 break;
3585 break;
3587 case EF_ARM_EABI_VER2:
3588 out = stpcpy (out, ", Version2 EABI");
3589 while (e_flags)
3591 unsigned flag;
3593 /* Process flags one bit at a time. */
3594 flag = e_flags & - e_flags;
3595 e_flags &= ~ flag;
3597 switch (flag)
3599 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
3600 out = stpcpy (out, ", sorted symbol tables");
3601 break;
3603 case EF_ARM_DYNSYMSUSESEGIDX:
3604 out = stpcpy (out, ", dynamic symbols use segment index");
3605 break;
3607 case EF_ARM_MAPSYMSFIRST:
3608 out = stpcpy (out, ", mapping symbols precede others");
3609 break;
3611 default:
3612 unknown = true;
3613 break;
3616 break;
3618 case EF_ARM_EABI_VER3:
3619 out = stpcpy (out, ", Version3 EABI");
3620 break;
3622 case EF_ARM_EABI_VER4:
3623 out = stpcpy (out, ", Version4 EABI");
3624 while (e_flags)
3626 unsigned flag;
3628 /* Process flags one bit at a time. */
3629 flag = e_flags & - e_flags;
3630 e_flags &= ~ flag;
3632 switch (flag)
3634 case EF_ARM_BE8:
3635 out = stpcpy (out, ", BE8");
3636 break;
3638 case EF_ARM_LE8:
3639 out = stpcpy (out, ", LE8");
3640 break;
3642 default:
3643 unknown = true;
3644 break;
3647 break;
3649 case EF_ARM_EABI_VER5:
3650 out = stpcpy (out, ", Version5 EABI");
3651 while (e_flags)
3653 unsigned flag;
3655 /* Process flags one bit at a time. */
3656 flag = e_flags & - e_flags;
3657 e_flags &= ~ flag;
3659 switch (flag)
3661 case EF_ARM_BE8:
3662 out = stpcpy (out, ", BE8");
3663 break;
3665 case EF_ARM_LE8:
3666 out = stpcpy (out, ", LE8");
3667 break;
3669 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
3670 out = stpcpy (out, ", soft-float ABI");
3671 break;
3673 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
3674 out = stpcpy (out, ", hard-float ABI");
3675 break;
3677 default:
3678 unknown = true;
3679 break;
3682 break;
3684 case EF_ARM_EABI_UNKNOWN:
3685 out = stpcpy (out, ", GNU EABI");
3686 while (e_flags)
3688 unsigned flag;
3690 /* Process flags one bit at a time. */
3691 flag = e_flags & - e_flags;
3692 e_flags &= ~ flag;
3694 switch (flag)
3696 case EF_ARM_INTERWORK:
3697 out = stpcpy (out, ", interworking enabled");
3698 break;
3700 case EF_ARM_APCS_26:
3701 out = stpcpy (out, ", uses APCS/26");
3702 break;
3704 case EF_ARM_APCS_FLOAT:
3705 out = stpcpy (out, ", uses APCS/float");
3706 break;
3708 case EF_ARM_PIC:
3709 out = stpcpy (out, ", position independent");
3710 break;
3712 case EF_ARM_ALIGN8:
3713 out = stpcpy (out, ", 8 bit structure alignment");
3714 break;
3716 case EF_ARM_NEW_ABI:
3717 out = stpcpy (out, ", uses new ABI");
3718 break;
3720 case EF_ARM_OLD_ABI:
3721 out = stpcpy (out, ", uses old ABI");
3722 break;
3724 case EF_ARM_SOFT_FLOAT:
3725 out = stpcpy (out, ", software FP");
3726 break;
3728 case EF_ARM_VFP_FLOAT:
3729 out = stpcpy (out, ", VFP");
3730 break;
3732 default:
3733 unknown = true;
3734 break;
3739 if (unknown)
3740 out = stpcpy (out,_(", <unknown>"));
3741 return out;
3744 static char *
3745 decode_AVR_machine_flags (char *out, unsigned e_flags)
3747 switch (e_flags & EF_AVR_MACH)
3749 case E_AVR_MACH_AVR1:
3750 out = stpcpy (out, ", avr:1");
3751 break;
3752 case E_AVR_MACH_AVR2:
3753 out = stpcpy (out, ", avr:2");
3754 break;
3755 case E_AVR_MACH_AVR25:
3756 out = stpcpy (out, ", avr:25");
3757 break;
3758 case E_AVR_MACH_AVR3:
3759 out = stpcpy (out, ", avr:3");
3760 break;
3761 case E_AVR_MACH_AVR31:
3762 out = stpcpy (out, ", avr:31");
3763 break;
3764 case E_AVR_MACH_AVR35:
3765 out = stpcpy (out, ", avr:35");
3766 break;
3767 case E_AVR_MACH_AVR4:
3768 out = stpcpy (out, ", avr:4");
3769 break;
3770 case E_AVR_MACH_AVR5:
3771 out = stpcpy (out, ", avr:5");
3772 break;
3773 case E_AVR_MACH_AVR51:
3774 out = stpcpy (out, ", avr:51");
3775 break;
3776 case E_AVR_MACH_AVR6:
3777 out = stpcpy (out, ", avr:6");
3778 break;
3779 case E_AVR_MACH_AVRTINY:
3780 out = stpcpy (out, ", avr:100");
3781 break;
3782 case E_AVR_MACH_XMEGA1:
3783 out = stpcpy (out, ", avr:101");
3784 break;
3785 case E_AVR_MACH_XMEGA2:
3786 out = stpcpy (out, ", avr:102");
3787 break;
3788 case E_AVR_MACH_XMEGA3:
3789 out = stpcpy (out, ", avr:103");
3790 break;
3791 case E_AVR_MACH_XMEGA4:
3792 out = stpcpy (out, ", avr:104");
3793 break;
3794 case E_AVR_MACH_XMEGA5:
3795 out = stpcpy (out, ", avr:105");
3796 break;
3797 case E_AVR_MACH_XMEGA6:
3798 out = stpcpy (out, ", avr:106");
3799 break;
3800 case E_AVR_MACH_XMEGA7:
3801 out = stpcpy (out, ", avr:107");
3802 break;
3803 default:
3804 out = stpcpy (out, ", avr:<unknown>");
3805 break;
3808 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
3809 out = stpcpy (out, ", link-relax");
3810 return out;
3813 static char *
3814 decode_BLACKFIN_machine_flags (char *out, unsigned e_flags)
3816 if (e_flags & EF_BFIN_PIC)
3817 out = stpcpy (out, ", PIC");
3819 if (e_flags & EF_BFIN_FDPIC)
3820 out = stpcpy (out, ", FDPIC");
3822 if (e_flags & EF_BFIN_CODE_IN_L1)
3823 out = stpcpy (out, ", code in L1");
3825 if (e_flags & EF_BFIN_DATA_IN_L1)
3826 out = stpcpy (out, ", data in L1");
3827 return out;
3830 static char *
3831 decode_FRV_machine_flags (char *out, unsigned e_flags)
3833 switch (e_flags & EF_FRV_CPU_MASK)
3835 case EF_FRV_CPU_GENERIC:
3836 break;
3838 default:
3839 out = stpcpy (out, ", fr???");
3840 break;
3842 case EF_FRV_CPU_FR300:
3843 out = stpcpy (out, ", fr300");
3844 break;
3846 case EF_FRV_CPU_FR400:
3847 out = stpcpy (out, ", fr400");
3848 break;
3849 case EF_FRV_CPU_FR405:
3850 out = stpcpy (out, ", fr405");
3851 break;
3853 case EF_FRV_CPU_FR450:
3854 out = stpcpy (out, ", fr450");
3855 break;
3857 case EF_FRV_CPU_FR500:
3858 out = stpcpy (out, ", fr500");
3859 break;
3860 case EF_FRV_CPU_FR550:
3861 out = stpcpy (out, ", fr550");
3862 break;
3864 case EF_FRV_CPU_SIMPLE:
3865 out = stpcpy (out, ", simple");
3866 break;
3867 case EF_FRV_CPU_TOMCAT:
3868 out = stpcpy (out, ", tomcat");
3869 break;
3871 return out;
3874 static char *
3875 decode_IA64_machine_flags (char *out, unsigned e_flags, Filedata *filedata)
3877 if ((e_flags & EF_IA_64_ABI64))
3878 out = stpcpy (out, ", 64-bit");
3879 else
3880 out = stpcpy (out, ", 32-bit");
3881 if ((e_flags & EF_IA_64_REDUCEDFP))
3882 out = stpcpy (out, ", reduced fp model");
3883 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3884 out = stpcpy (out, ", no function descriptors, constant gp");
3885 else if ((e_flags & EF_IA_64_CONS_GP))
3886 out = stpcpy (out, ", constant gp");
3887 if ((e_flags & EF_IA_64_ABSOLUTE))
3888 out = stpcpy (out, ", absolute");
3889 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
3891 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3892 out = stpcpy (out, ", vms_linkages");
3893 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3895 case EF_IA_64_VMS_COMCOD_SUCCESS:
3896 break;
3897 case EF_IA_64_VMS_COMCOD_WARNING:
3898 out = stpcpy (out, ", warning");
3899 break;
3900 case EF_IA_64_VMS_COMCOD_ERROR:
3901 out = stpcpy (out, ", error");
3902 break;
3903 case EF_IA_64_VMS_COMCOD_ABORT:
3904 out = stpcpy (out, ", abort");
3905 break;
3906 default:
3907 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3908 e_flags & EF_IA_64_VMS_COMCOD);
3909 out = stpcpy (out, ", <unknown>");
3912 return out;
3915 static char *
3916 decode_LOONGARCH_machine_flags (char *out, unsigned int e_flags)
3918 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
3919 out = stpcpy (out, ", SOFT-FLOAT");
3920 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
3921 out = stpcpy (out, ", SINGLE-FLOAT");
3922 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
3923 out = stpcpy (out, ", DOUBLE-FLOAT");
3925 if (EF_LOONGARCH_IS_OBJ_V0 (e_flags))
3926 out = stpcpy (out, ", OBJ-v0");
3927 else if (EF_LOONGARCH_IS_OBJ_V1 (e_flags))
3928 out = stpcpy (out, ", OBJ-v1");
3929 return out;
3932 static char *
3933 decode_M68K_machine_flags (char *out, unsigned int e_flags)
3935 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
3936 out = stpcpy (out, ", m68000");
3937 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3938 out = stpcpy (out, ", cpu32");
3939 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3940 out = stpcpy (out, ", fido_a");
3941 else
3943 char const *isa = _("unknown");
3944 char const *mac = _("unknown mac");
3945 char const *additional = NULL;
3947 switch (e_flags & EF_M68K_CF_ISA_MASK)
3949 case EF_M68K_CF_ISA_A_NODIV:
3950 isa = "A";
3951 additional = ", nodiv";
3952 break;
3953 case EF_M68K_CF_ISA_A:
3954 isa = "A";
3955 break;
3956 case EF_M68K_CF_ISA_A_PLUS:
3957 isa = "A+";
3958 break;
3959 case EF_M68K_CF_ISA_B_NOUSP:
3960 isa = "B";
3961 additional = ", nousp";
3962 break;
3963 case EF_M68K_CF_ISA_B:
3964 isa = "B";
3965 break;
3966 case EF_M68K_CF_ISA_C:
3967 isa = "C";
3968 break;
3969 case EF_M68K_CF_ISA_C_NODIV:
3970 isa = "C";
3971 additional = ", nodiv";
3972 break;
3974 out = stpcpy (out, ", cf, isa ");
3975 out = stpcpy (out, isa);
3976 if (additional)
3977 out = stpcpy (out, additional);
3978 if (e_flags & EF_M68K_CF_FLOAT)
3979 out = stpcpy (out, ", float");
3980 switch (e_flags & EF_M68K_CF_MAC_MASK)
3982 case 0:
3983 mac = NULL;
3984 break;
3985 case EF_M68K_CF_MAC:
3986 mac = "mac";
3987 break;
3988 case EF_M68K_CF_EMAC:
3989 mac = "emac";
3990 break;
3991 case EF_M68K_CF_EMAC_B:
3992 mac = "emac_b";
3993 break;
3995 if (mac)
3997 out = stpcpy (out, ", ");
3998 out = stpcpy (out, mac);
4001 return out;
4004 static char *
4005 decode_MeP_machine_flags (char *out, unsigned int e_flags)
4007 switch (e_flags & EF_MEP_CPU_MASK)
4009 case EF_MEP_CPU_MEP:
4010 out = stpcpy (out, ", generic MeP");
4011 break;
4012 case EF_MEP_CPU_C2:
4013 out = stpcpy (out, ", MeP C2");
4014 break;
4015 case EF_MEP_CPU_C3:
4016 out = stpcpy (out, ", MeP C3");
4017 break;
4018 case EF_MEP_CPU_C4:
4019 out = stpcpy (out, ", MeP C4");
4020 break;
4021 case EF_MEP_CPU_C5:
4022 out = stpcpy (out, ", MeP C5");
4023 break;
4024 case EF_MEP_CPU_H1:
4025 out = stpcpy (out, ", MeP H1");
4026 break;
4027 default:
4028 out = stpcpy (out, _(", <unknown MeP cpu type>"));
4029 break;
4032 switch (e_flags & EF_MEP_COP_MASK)
4034 case EF_MEP_COP_NONE:
4035 break;
4036 case EF_MEP_COP_AVC:
4037 out = stpcpy (out, ", AVC coprocessor");
4038 break;
4039 case EF_MEP_COP_AVC2:
4040 out = stpcpy (out, ", AVC2 coprocessor");
4041 break;
4042 case EF_MEP_COP_FMAX:
4043 out = stpcpy (out, ", FMAX coprocessor");
4044 break;
4045 case EF_MEP_COP_IVC2:
4046 out = stpcpy (out, ", IVC2 coprocessor");
4047 break;
4048 default:
4049 out = stpcpy (out, _("<unknown MeP copro type>"));
4050 break;
4053 if (e_flags & EF_MEP_LIBRARY)
4054 out = stpcpy (out, ", Built for Library");
4056 if (e_flags & EF_MEP_INDEX_MASK)
4057 out += sprintf (out, ", Configuration Index: %#x",
4058 e_flags & EF_MEP_INDEX_MASK);
4060 if (e_flags & ~ EF_MEP_ALL_FLAGS)
4061 out += sprintf (out, _(", unknown flags bits: %#x"),
4062 e_flags & ~ EF_MEP_ALL_FLAGS);
4063 return out;
4066 static char *
4067 decode_MIPS_machine_flags (char *out, unsigned int e_flags)
4069 if (e_flags & EF_MIPS_NOREORDER)
4070 out = stpcpy (out, ", noreorder");
4072 if (e_flags & EF_MIPS_PIC)
4073 out = stpcpy (out, ", pic");
4075 if (e_flags & EF_MIPS_CPIC)
4076 out = stpcpy (out, ", cpic");
4078 if (e_flags & EF_MIPS_UCODE)
4079 out = stpcpy (out, ", ugen_reserved");
4081 if (e_flags & EF_MIPS_ABI2)
4082 out = stpcpy (out, ", abi2");
4084 if (e_flags & EF_MIPS_OPTIONS_FIRST)
4085 out = stpcpy (out, ", odk first");
4087 if (e_flags & EF_MIPS_32BITMODE)
4088 out = stpcpy (out, ", 32bitmode");
4090 if (e_flags & EF_MIPS_NAN2008)
4091 out = stpcpy (out, ", nan2008");
4093 if (e_flags & EF_MIPS_FP64)
4094 out = stpcpy (out, ", fp64");
4096 switch ((e_flags & EF_MIPS_MACH))
4098 case EF_MIPS_MACH_3900:
4099 out = stpcpy (out, ", 3900");
4100 break;
4101 case EF_MIPS_MACH_4010:
4102 out = stpcpy (out, ", 4010");
4103 break;
4104 case EF_MIPS_MACH_4100:
4105 out = stpcpy (out, ", 4100");
4106 break;
4107 case EF_MIPS_MACH_4111:
4108 out = stpcpy (out, ", 4111");
4109 break;
4110 case EF_MIPS_MACH_4120:
4111 out = stpcpy (out, ", 4120");
4112 break;
4113 case EF_MIPS_MACH_4650:
4114 out = stpcpy (out, ", 4650");
4115 break;
4116 case EF_MIPS_MACH_5400:
4117 out = stpcpy (out, ", 5400");
4118 break;
4119 case EF_MIPS_MACH_5500:
4120 out = stpcpy (out, ", 5500");
4121 break;
4122 case EF_MIPS_MACH_5900:
4123 out = stpcpy (out, ", 5900");
4124 break;
4125 case EF_MIPS_MACH_SB1:
4126 out = stpcpy (out, ", sb1");
4127 break;
4128 case EF_MIPS_MACH_9000:
4129 out = stpcpy (out, ", 9000");
4130 break;
4131 case EF_MIPS_MACH_LS2E:
4132 out = stpcpy (out, ", loongson-2e");
4133 break;
4134 case EF_MIPS_MACH_LS2F:
4135 out = stpcpy (out, ", loongson-2f");
4136 break;
4137 case EF_MIPS_MACH_GS464:
4138 out = stpcpy (out, ", gs464");
4139 break;
4140 case EF_MIPS_MACH_GS464E:
4141 out = stpcpy (out, ", gs464e");
4142 break;
4143 case EF_MIPS_MACH_GS264E:
4144 out = stpcpy (out, ", gs264e");
4145 break;
4146 case EF_MIPS_MACH_OCTEON:
4147 out = stpcpy (out, ", octeon");
4148 break;
4149 case EF_MIPS_MACH_OCTEON2:
4150 out = stpcpy (out, ", octeon2");
4151 break;
4152 case EF_MIPS_MACH_OCTEON3:
4153 out = stpcpy (out, ", octeon3");
4154 break;
4155 case EF_MIPS_MACH_XLR:
4156 out = stpcpy (out, ", xlr");
4157 break;
4158 case EF_MIPS_MACH_IAMR2:
4159 out = stpcpy (out, ", interaptiv-mr2");
4160 break;
4161 case EF_MIPS_MACH_ALLEGREX:
4162 out = stpcpy (out, ", allegrex");
4163 break;
4164 case 0:
4165 /* We simply ignore the field in this case to avoid confusion:
4166 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
4167 extension. */
4168 break;
4169 default:
4170 out = stpcpy (out, _(", unknown CPU"));
4171 break;
4174 switch ((e_flags & EF_MIPS_ABI))
4176 case EF_MIPS_ABI_O32:
4177 out = stpcpy (out, ", o32");
4178 break;
4179 case EF_MIPS_ABI_O64:
4180 out = stpcpy (out, ", o64");
4181 break;
4182 case EF_MIPS_ABI_EABI32:
4183 out = stpcpy (out, ", eabi32");
4184 break;
4185 case EF_MIPS_ABI_EABI64:
4186 out = stpcpy (out, ", eabi64");
4187 break;
4188 case 0:
4189 /* We simply ignore the field in this case to avoid confusion:
4190 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
4191 This means it is likely to be an o32 file, but not for
4192 sure. */
4193 break;
4194 default:
4195 out = stpcpy (out, _(", unknown ABI"));
4196 break;
4199 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
4200 out = stpcpy (out, ", mdmx");
4202 if (e_flags & EF_MIPS_ARCH_ASE_M16)
4203 out = stpcpy (out, ", mips16");
4205 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
4206 out = stpcpy (out, ", micromips");
4208 switch ((e_flags & EF_MIPS_ARCH))
4210 case EF_MIPS_ARCH_1:
4211 out = stpcpy (out, ", mips1");
4212 break;
4213 case EF_MIPS_ARCH_2:
4214 out = stpcpy (out, ", mips2");
4215 break;
4216 case EF_MIPS_ARCH_3:
4217 out = stpcpy (out, ", mips3");
4218 break;
4219 case EF_MIPS_ARCH_4:
4220 out = stpcpy (out, ", mips4");
4221 break;
4222 case EF_MIPS_ARCH_5:
4223 out = stpcpy (out, ", mips5");
4224 break;
4225 case EF_MIPS_ARCH_32:
4226 out = stpcpy (out, ", mips32");
4227 break;
4228 case EF_MIPS_ARCH_32R2:
4229 out = stpcpy (out, ", mips32r2");
4230 break;
4231 case EF_MIPS_ARCH_32R6:
4232 out = stpcpy (out, ", mips32r6");
4233 break;
4234 case EF_MIPS_ARCH_64:
4235 out = stpcpy (out, ", mips64");
4236 break;
4237 case EF_MIPS_ARCH_64R2:
4238 out = stpcpy (out, ", mips64r2");
4239 break;
4240 case EF_MIPS_ARCH_64R6:
4241 out = stpcpy (out, ", mips64r6");
4242 break;
4243 default:
4244 out = stpcpy (out, _(", unknown ISA"));
4245 break;
4247 return out;
4250 static char *
4251 decode_MSP430_machine_flags (char *out, unsigned e_flags)
4253 out = stpcpy (out, _(": architecture variant: "));
4254 switch (e_flags & EF_MSP430_MACH)
4256 case E_MSP430_MACH_MSP430x11:
4257 out = stpcpy (out, "MSP430x11");
4258 break;
4259 case E_MSP430_MACH_MSP430x11x1:
4260 out = stpcpy (out, "MSP430x11x1 ");
4261 break;
4262 case E_MSP430_MACH_MSP430x12:
4263 out = stpcpy (out, "MSP430x12");
4264 break;
4265 case E_MSP430_MACH_MSP430x13:
4266 out = stpcpy (out, "MSP430x13");
4267 break;
4268 case E_MSP430_MACH_MSP430x14:
4269 out = stpcpy (out, "MSP430x14");
4270 break;
4271 case E_MSP430_MACH_MSP430x15:
4272 out = stpcpy (out, "MSP430x15");
4273 break;
4274 case E_MSP430_MACH_MSP430x16:
4275 out = stpcpy (out, "MSP430x16");
4276 break;
4277 case E_MSP430_MACH_MSP430x31:
4278 out = stpcpy (out, "MSP430x31");
4279 break;
4280 case E_MSP430_MACH_MSP430x32:
4281 out = stpcpy (out, "MSP430x32");
4282 break;
4283 case E_MSP430_MACH_MSP430x33:
4284 out = stpcpy (out, "MSP430x33");
4285 break;
4286 case E_MSP430_MACH_MSP430x41:
4287 out = stpcpy (out, "MSP430x41");
4288 break;
4289 case E_MSP430_MACH_MSP430x42:
4290 out = stpcpy (out, "MSP430x42");
4291 break;
4292 case E_MSP430_MACH_MSP430x43:
4293 out = stpcpy (out, "MSP430x43");
4294 break;
4295 case E_MSP430_MACH_MSP430x44:
4296 out = stpcpy (out, "MSP430x44");
4297 break;
4298 case E_MSP430_MACH_MSP430X :
4299 out = stpcpy (out, "MSP430X");
4300 break;
4301 default:
4302 out = stpcpy (out, _(": unknown"));
4303 break;
4306 if (e_flags & ~ EF_MSP430_MACH)
4307 out = stpcpy (out, _(": unknown extra flag bits also present"));
4308 return out;
4311 static char *
4312 decode_NDS32_machine_flags (char *out, unsigned e_flags)
4314 unsigned abi;
4315 unsigned arch;
4316 unsigned config;
4317 unsigned version;
4318 bool has_fpu = false;
4320 static const char *ABI_STRINGS[] =
4322 "ABI v0", /* use r5 as return register; only used in N1213HC */
4323 "ABI v1", /* use r0 as return register */
4324 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
4325 "ABI v2fp", /* for FPU */
4326 "AABI",
4327 "ABI2 FP+"
4329 static const char *VER_STRINGS[] =
4331 "Andes ELF V1.3 or older",
4332 "Andes ELF V1.3.1",
4333 "Andes ELF V1.4"
4335 static const char *ARCH_STRINGS[] =
4338 "Andes Star v1.0",
4339 "Andes Star v2.0",
4340 "Andes Star v3.0",
4341 "Andes Star v3.0m"
4344 abi = EF_NDS_ABI & e_flags;
4345 arch = EF_NDS_ARCH & e_flags;
4346 config = EF_NDS_INST & e_flags;
4347 version = EF_NDS32_ELF_VERSION & e_flags;
4349 switch (abi)
4351 case E_NDS_ABI_V0:
4352 case E_NDS_ABI_V1:
4353 case E_NDS_ABI_V2:
4354 case E_NDS_ABI_V2FP:
4355 case E_NDS_ABI_AABI:
4356 case E_NDS_ABI_V2FP_PLUS:
4357 /* In case there are holes in the array. */
4358 out += sprintf (out, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
4359 break;
4361 default:
4362 out = stpcpy (out, ", <unrecognized ABI>");
4363 break;
4366 switch (version)
4368 case E_NDS32_ELF_VER_1_2:
4369 case E_NDS32_ELF_VER_1_3:
4370 case E_NDS32_ELF_VER_1_4:
4371 out += sprintf (out, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
4372 break;
4374 default:
4375 out = stpcpy (out, ", <unrecognized ELF version number>");
4376 break;
4379 if (E_NDS_ABI_V0 == abi)
4381 /* OLD ABI; only used in N1213HC, has performance extension 1. */
4382 out = stpcpy (out, ", Andes Star v1.0, N1213HC, MAC, PERF1");
4383 if (arch == E_NDS_ARCH_STAR_V1_0)
4384 out = stpcpy (out, ", 16b"); /* has 16-bit instructions */
4385 return out;
4388 switch (arch)
4390 case E_NDS_ARCH_STAR_V1_0:
4391 case E_NDS_ARCH_STAR_V2_0:
4392 case E_NDS_ARCH_STAR_V3_0:
4393 case E_NDS_ARCH_STAR_V3_M:
4394 out += sprintf (out, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
4395 break;
4397 default:
4398 out = stpcpy (out, ", <unrecognized architecture>");
4399 /* ARCH version determines how the e_flags are interpreted.
4400 If it is unknown, we cannot proceed. */
4401 return out;
4404 /* Newer ABI; Now handle architecture specific flags. */
4405 if (arch == E_NDS_ARCH_STAR_V1_0)
4407 if (config & E_NDS32_HAS_MFUSR_PC_INST)
4408 out = stpcpy (out, ", MFUSR_PC");
4410 if (!(config & E_NDS32_HAS_NO_MAC_INST))
4411 out = stpcpy (out, ", MAC");
4413 if (config & E_NDS32_HAS_DIV_INST)
4414 out = stpcpy (out, ", DIV");
4416 if (config & E_NDS32_HAS_16BIT_INST)
4417 out = stpcpy (out, ", 16b");
4419 else
4421 if (config & E_NDS32_HAS_MFUSR_PC_INST)
4423 if (version <= E_NDS32_ELF_VER_1_3)
4424 out = stpcpy (out, ", [B8]");
4425 else
4426 out = stpcpy (out, ", EX9");
4429 if (config & E_NDS32_HAS_MAC_DX_INST)
4430 out = stpcpy (out, ", MAC_DX");
4432 if (config & E_NDS32_HAS_DIV_DX_INST)
4433 out = stpcpy (out, ", DIV_DX");
4435 if (config & E_NDS32_HAS_16BIT_INST)
4437 if (version <= E_NDS32_ELF_VER_1_3)
4438 out = stpcpy (out, ", 16b");
4439 else
4440 out = stpcpy (out, ", IFC");
4444 if (config & E_NDS32_HAS_EXT_INST)
4445 out = stpcpy (out, ", PERF1");
4447 if (config & E_NDS32_HAS_EXT2_INST)
4448 out = stpcpy (out, ", PERF2");
4450 if (config & E_NDS32_HAS_FPU_INST)
4452 has_fpu = true;
4453 out = stpcpy (out, ", FPU_SP");
4456 if (config & E_NDS32_HAS_FPU_DP_INST)
4458 has_fpu = true;
4459 out = stpcpy (out, ", FPU_DP");
4462 if (config & E_NDS32_HAS_FPU_MAC_INST)
4464 has_fpu = true;
4465 out = stpcpy (out, ", FPU_MAC");
4468 if (has_fpu)
4470 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
4472 case E_NDS32_FPU_REG_8SP_4DP:
4473 out = stpcpy (out, ", FPU_REG:8/4");
4474 break;
4475 case E_NDS32_FPU_REG_16SP_8DP:
4476 out = stpcpy (out, ", FPU_REG:16/8");
4477 break;
4478 case E_NDS32_FPU_REG_32SP_16DP:
4479 out = stpcpy (out, ", FPU_REG:32/16");
4480 break;
4481 case E_NDS32_FPU_REG_32SP_32DP:
4482 out = stpcpy (out, ", FPU_REG:32/32");
4483 break;
4487 if (config & E_NDS32_HAS_AUDIO_INST)
4488 out = stpcpy (out, ", AUDIO");
4490 if (config & E_NDS32_HAS_STRING_INST)
4491 out = stpcpy (out, ", STR");
4493 if (config & E_NDS32_HAS_REDUCED_REGS)
4494 out = stpcpy (out, ", 16REG");
4496 if (config & E_NDS32_HAS_VIDEO_INST)
4498 if (version <= E_NDS32_ELF_VER_1_3)
4499 out = stpcpy (out, ", VIDEO");
4500 else
4501 out = stpcpy (out, ", SATURATION");
4504 if (config & E_NDS32_HAS_ENCRIPT_INST)
4505 out = stpcpy (out, ", ENCRP");
4507 if (config & E_NDS32_HAS_L2C_INST)
4508 out = stpcpy (out, ", L2C");
4510 return out;
4513 static char *
4514 decode_PARISC_machine_flags (char *out, unsigned e_flags)
4516 switch (e_flags & EF_PARISC_ARCH)
4518 case EFA_PARISC_1_0:
4519 out = stpcpy (out, ", PA-RISC 1.0");
4520 break;
4521 case EFA_PARISC_1_1:
4522 out = stpcpy (out, ", PA-RISC 1.1");
4523 break;
4524 case EFA_PARISC_2_0:
4525 out = stpcpy (out, ", PA-RISC 2.0");
4526 break;
4527 default:
4528 break;
4530 if (e_flags & EF_PARISC_TRAPNIL)
4531 out = stpcpy (out, ", trapnil");
4532 if (e_flags & EF_PARISC_EXT)
4533 out = stpcpy (out, ", ext");
4534 if (e_flags & EF_PARISC_LSB)
4535 out = stpcpy (out, ", lsb");
4536 if (e_flags & EF_PARISC_WIDE)
4537 out = stpcpy (out, ", wide");
4538 if (e_flags & EF_PARISC_NO_KABP)
4539 out = stpcpy (out, ", no kabp");
4540 if (e_flags & EF_PARISC_LAZYSWAP)
4541 out = stpcpy (out, ", lazyswap");
4542 return out;
4545 static char *
4546 decode_RISCV_machine_flags (char *out, unsigned e_flags)
4548 if (e_flags & EF_RISCV_RVC)
4549 out = stpcpy (out, ", RVC");
4551 if (e_flags & EF_RISCV_RVE)
4552 out = stpcpy (out, ", RVE");
4554 if (e_flags & EF_RISCV_TSO)
4555 out = stpcpy (out, ", TSO");
4557 switch (e_flags & EF_RISCV_FLOAT_ABI)
4559 case EF_RISCV_FLOAT_ABI_SOFT:
4560 out = stpcpy (out, ", soft-float ABI");
4561 break;
4563 case EF_RISCV_FLOAT_ABI_SINGLE:
4564 out = stpcpy (out, ", single-float ABI");
4565 break;
4567 case EF_RISCV_FLOAT_ABI_DOUBLE:
4568 out = stpcpy (out, ", double-float ABI");
4569 break;
4571 case EF_RISCV_FLOAT_ABI_QUAD:
4572 out = stpcpy (out, ", quad-float ABI");
4573 break;
4575 return out;
4578 static char *
4579 decode_RL78_machine_flags (char *out, unsigned e_flags)
4581 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4583 case E_FLAG_RL78_ANY_CPU:
4584 break;
4585 case E_FLAG_RL78_G10:
4586 out = stpcpy (out, ", G10");
4587 break;
4588 case E_FLAG_RL78_G13:
4589 out = stpcpy (out, ", G13");
4590 break;
4591 case E_FLAG_RL78_G14:
4592 out = stpcpy (out, ", G14");
4593 break;
4595 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4596 out = stpcpy (out, ", 64-bit doubles");
4597 return out;
4600 static char *
4601 decode_RX_machine_flags (char *out, unsigned e_flags)
4603 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4604 out = stpcpy (out, ", 64-bit doubles");
4605 if (e_flags & E_FLAG_RX_DSP)
4606 out = stpcpy (out, ", dsp");
4607 if (e_flags & E_FLAG_RX_PID)
4608 out = stpcpy (out, ", pid");
4609 if (e_flags & E_FLAG_RX_ABI)
4610 out = stpcpy (out, ", RX ABI");
4611 if (e_flags & E_FLAG_RX_SINSNS_SET)
4612 out = stpcpy (out, (e_flags & E_FLAG_RX_SINSNS_YES
4613 ? ", uses String instructions"
4614 : ", bans String instructions"));
4615 if (e_flags & E_FLAG_RX_V2)
4616 out = stpcpy (out, ", V2");
4617 if (e_flags & E_FLAG_RX_V3)
4618 out = stpcpy (out, ", V3");
4619 return out;
4622 static char *
4623 decode_SH_machine_flags (char *out, unsigned e_flags)
4625 switch ((e_flags & EF_SH_MACH_MASK))
4627 case EF_SH1:
4628 out = stpcpy (out, ", sh1");
4629 break;
4630 case EF_SH2:
4631 out = stpcpy (out, ", sh2");
4632 break;
4633 case EF_SH3:
4634 out = stpcpy (out, ", sh3");
4635 break;
4636 case EF_SH_DSP:
4637 out = stpcpy (out, ", sh-dsp");
4638 break;
4639 case EF_SH3_DSP:
4640 out = stpcpy (out, ", sh3-dsp");
4641 break;
4642 case EF_SH4AL_DSP:
4643 out = stpcpy (out, ", sh4al-dsp");
4644 break;
4645 case EF_SH3E:
4646 out = stpcpy (out, ", sh3e");
4647 break;
4648 case EF_SH4:
4649 out = stpcpy (out, ", sh4");
4650 break;
4651 case EF_SH5:
4652 out = stpcpy (out, ", sh5");
4653 break;
4654 case EF_SH2E:
4655 out = stpcpy (out, ", sh2e");
4656 break;
4657 case EF_SH4A:
4658 out = stpcpy (out, ", sh4a");
4659 break;
4660 case EF_SH2A:
4661 out = stpcpy (out, ", sh2a");
4662 break;
4663 case EF_SH4_NOFPU:
4664 out = stpcpy (out, ", sh4-nofpu");
4665 break;
4666 case EF_SH4A_NOFPU:
4667 out = stpcpy (out, ", sh4a-nofpu");
4668 break;
4669 case EF_SH2A_NOFPU:
4670 out = stpcpy (out, ", sh2a-nofpu");
4671 break;
4672 case EF_SH3_NOMMU:
4673 out = stpcpy (out, ", sh3-nommu");
4674 break;
4675 case EF_SH4_NOMMU_NOFPU:
4676 out = stpcpy (out, ", sh4-nommu-nofpu");
4677 break;
4678 case EF_SH2A_SH4_NOFPU:
4679 out = stpcpy (out, ", sh2a-nofpu-or-sh4-nommu-nofpu");
4680 break;
4681 case EF_SH2A_SH3_NOFPU:
4682 out = stpcpy (out, ", sh2a-nofpu-or-sh3-nommu");
4683 break;
4684 case EF_SH2A_SH4:
4685 out = stpcpy (out, ", sh2a-or-sh4");
4686 break;
4687 case EF_SH2A_SH3E:
4688 out = stpcpy (out, ", sh2a-or-sh3e");
4689 break;
4690 default:
4691 out = stpcpy (out, _(", unknown ISA"));
4692 break;
4695 if (e_flags & EF_SH_PIC)
4696 out = stpcpy (out, ", pic");
4698 if (e_flags & EF_SH_FDPIC)
4699 out = stpcpy (out, ", fdpic");
4700 return out;
4703 static char *
4704 decode_SPARC_machine_flags (char *out, unsigned e_flags)
4706 if (e_flags & EF_SPARC_32PLUS)
4707 out = stpcpy (out, ", v8+");
4709 if (e_flags & EF_SPARC_SUN_US1)
4710 out = stpcpy (out, ", ultrasparcI");
4712 if (e_flags & EF_SPARC_SUN_US3)
4713 out = stpcpy (out, ", ultrasparcIII");
4715 if (e_flags & EF_SPARC_HAL_R1)
4716 out = stpcpy (out, ", halr1");
4718 if (e_flags & EF_SPARC_LEDATA)
4719 out = stpcpy (out, ", ledata");
4721 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4722 out = stpcpy (out, ", tso");
4724 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4725 out = stpcpy (out, ", pso");
4727 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4728 out = stpcpy (out, ", rmo");
4729 return out;
4732 static char *
4733 decode_V800_machine_flags (char *out, unsigned int e_flags)
4735 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
4736 out = stpcpy (out, ", RH850 ABI");
4738 if (e_flags & EF_V800_850E3)
4739 out = stpcpy (out, ", V3 architecture");
4741 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
4742 out = stpcpy (out, ", FPU not used");
4744 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
4745 out = stpcpy (out, ", regmode: COMMON");
4747 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
4748 out = stpcpy (out, ", r4 not used");
4750 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
4751 out = stpcpy (out, ", r30 not used");
4753 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
4754 out = stpcpy (out, ", r5 not used");
4756 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
4757 out = stpcpy (out, ", r2 not used");
4759 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
4761 switch (e_flags & - e_flags)
4763 case EF_RH850_FPU_DOUBLE:
4764 out = stpcpy (out, ", double precision FPU");
4765 break;
4766 case EF_RH850_FPU_SINGLE:
4767 out = stpcpy (out, ", single precision FPU");
4768 break;
4769 case EF_RH850_REGMODE22:
4770 out = stpcpy (out, ", regmode:22");
4771 break;
4772 case EF_RH850_REGMODE32:
4773 out = stpcpy (out, ", regmode:23");
4774 break;
4775 case EF_RH850_GP_FIX:
4776 out = stpcpy (out, ", r4 fixed");
4777 break;
4778 case EF_RH850_GP_NOFIX:
4779 out = stpcpy (out, ", r4 free");
4780 break;
4781 case EF_RH850_EP_FIX:
4782 out = stpcpy (out, ", r30 fixed");
4783 break;
4784 case EF_RH850_EP_NOFIX:
4785 out = stpcpy (out, ", r30 free");
4786 break;
4787 case EF_RH850_TP_FIX:
4788 out = stpcpy (out, ", r5 fixed");
4789 break;
4790 case EF_RH850_TP_NOFIX:
4791 out = stpcpy (out, ", r5 free");
4792 break;
4793 case EF_RH850_REG2_RESERVE:
4794 out = stpcpy (out, ", r2 fixed");
4795 break;
4796 case EF_RH850_REG2_NORESERVE:
4797 out = stpcpy (out, ", r2 free");
4798 break;
4799 default:
4800 break;
4803 return out;
4806 static char *
4807 decode_V850_machine_flags (char *out, unsigned int e_flags)
4809 switch (e_flags & EF_V850_ARCH)
4811 case E_V850E3V5_ARCH:
4812 out = stpcpy (out, ", v850e3v5");
4813 break;
4814 case E_V850E2V3_ARCH:
4815 out = stpcpy (out, ", v850e2v3");
4816 break;
4817 case E_V850E2_ARCH:
4818 out = stpcpy (out, ", v850e2");
4819 break;
4820 case E_V850E1_ARCH:
4821 out = stpcpy (out, ", v850e1");
4822 break;
4823 case E_V850E_ARCH:
4824 out = stpcpy (out, ", v850e");
4825 break;
4826 case E_V850_ARCH:
4827 out = stpcpy (out, ", v850");
4828 break;
4829 default:
4830 out = stpcpy (out, _(", unknown v850 architecture variant"));
4831 break;
4833 return out;
4836 static char *
4837 decode_Z80_machine_flags (char *out, unsigned int e_flags)
4839 switch (e_flags & EF_Z80_MACH_MSK)
4841 case EF_Z80_MACH_Z80:
4842 out = stpcpy (out, ", Z80");
4843 break;
4844 case EF_Z80_MACH_Z180:
4845 out = stpcpy (out, ", Z180");
4846 break;
4847 case EF_Z80_MACH_R800:
4848 out = stpcpy (out, ", R800");
4849 break;
4850 case EF_Z80_MACH_EZ80_Z80:
4851 out = stpcpy (out, ", EZ80");
4852 break;
4853 case EF_Z80_MACH_EZ80_ADL:
4854 out = stpcpy (out, ", EZ80, ADL");
4855 break;
4856 case EF_Z80_MACH_GBZ80:
4857 out = stpcpy (out, ", GBZ80");
4858 break;
4859 case EF_Z80_MACH_Z80N:
4860 out = stpcpy (out, ", Z80N");
4861 break;
4862 default:
4863 out = stpcpy (out, _(", unknown"));
4864 break;
4866 return out;
4869 static char *
4870 decode_AMDGPU_machine_flags (char *out, unsigned int e_flags, Filedata *filedata)
4872 unsigned char *e_ident = filedata->file_header.e_ident;
4873 unsigned char osabi = e_ident[EI_OSABI];
4874 unsigned char abiversion = e_ident[EI_ABIVERSION];
4875 unsigned int mach;
4877 /* HSA OS ABI v2 used a different encoding, but we don't need to support it,
4878 it has been deprecated for a while.
4880 The PAL, MESA3D and NONE OS ABIs are not properly versioned, at the time
4881 of writing, they use the same flags as HSA v3, so the code below uses that
4882 assumption. */
4883 if (osabi == ELFOSABI_AMDGPU_HSA && abiversion < ELFABIVERSION_AMDGPU_HSA_V3)
4884 return out;
4886 mach = e_flags & EF_AMDGPU_MACH;
4887 switch (mach)
4889 #define AMDGPU_CASE(code, string) \
4890 case code: out = stpcpy (out, ", " string); break;
4891 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600")
4892 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601")
4893 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700")
4894 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701")
4895 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702")
4896 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703")
4897 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704")
4898 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801")
4899 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802")
4900 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803")
4901 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810")
4902 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900")
4903 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902")
4904 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904")
4905 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906")
4906 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908")
4907 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909")
4908 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c")
4909 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010")
4910 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011")
4911 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012")
4912 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030")
4913 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031")
4914 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032")
4915 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033")
4916 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1100, "gfx1100")
4917 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1101, "gfx1101")
4918 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1102, "gfx1102")
4919 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602")
4920 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705")
4921 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805")
4922 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035")
4923 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034")
4924 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a")
4925 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940")
4926 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013")
4927 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036")
4928 default:
4929 out += sprintf (out, _(", <unknown AMDGPU GPU type: %#x>"), mach);
4930 break;
4931 #undef AMDGPU_CASE
4934 e_flags &= ~EF_AMDGPU_MACH;
4936 if ((osabi == ELFOSABI_AMDGPU_HSA
4937 && abiversion == ELFABIVERSION_AMDGPU_HSA_V3)
4938 || osabi != ELFOSABI_AMDGPU_HSA)
4940 /* For HSA v3 and other OS ABIs. */
4941 if (e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
4943 out = stpcpy (out, ", xnack on");
4944 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V3;
4947 if (e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
4949 out = stpcpy (out, ", sramecc on");
4950 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V3;
4953 else
4955 /* For HSA v4+. */
4956 int xnack, sramecc;
4958 xnack = e_flags & EF_AMDGPU_FEATURE_XNACK_V4;
4959 switch (xnack)
4961 case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
4962 break;
4964 case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
4965 out = stpcpy (out, ", xnack any");
4966 break;
4968 case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
4969 out = stpcpy (out, ", xnack off");
4970 break;
4972 case EF_AMDGPU_FEATURE_XNACK_ON_V4:
4973 out = stpcpy (out, ", xnack on");
4974 break;
4976 default:
4977 out += sprintf (out, _(", <unknown xnack value: %#x>"), xnack);
4978 break;
4981 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V4;
4983 sramecc = e_flags & EF_AMDGPU_FEATURE_SRAMECC_V4;
4984 switch (sramecc)
4986 case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
4987 break;
4989 case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
4990 out = stpcpy (out, ", sramecc any");
4991 break;
4993 case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
4994 out = stpcpy (out, ", sramecc off");
4995 break;
4997 case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
4998 out = stpcpy (out, ", sramecc on");
4999 break;
5001 default:
5002 out += sprintf (out, _(", <unknown sramecc value: %#x>"), sramecc);
5003 break;
5006 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V4;
5009 if (e_flags != 0)
5010 out += sprintf (out, _(", unknown flags bits: %#x"), e_flags);
5011 return out;
5014 static char *
5015 get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
5017 static char buf[1024];
5018 char *out = buf;
5020 buf[0] = '\0';
5022 if (e_flags)
5024 switch (e_machine)
5026 default:
5027 break;
5029 case EM_ARC_COMPACT3:
5030 out = stpcpy (out, ", HS5x");
5031 break;
5033 case EM_ARC_COMPACT3_64:
5034 out = stpcpy (out, ", HS6x");
5035 break;
5037 case EM_ARC_COMPACT2:
5038 case EM_ARC_COMPACT:
5039 out = decode_ARC_machine_flags (out, e_flags, e_machine);
5040 break;
5042 case EM_ARM:
5043 out = decode_ARM_machine_flags (out, e_flags);
5044 break;
5046 case EM_AVR:
5047 out = decode_AVR_machine_flags (out, e_flags);
5048 break;
5050 case EM_BLACKFIN:
5051 out = decode_BLACKFIN_machine_flags (out, e_flags);
5052 break;
5054 case EM_CYGNUS_FRV:
5055 out = decode_FRV_machine_flags (out, e_flags);
5056 break;
5058 case EM_68K:
5059 out = decode_M68K_machine_flags (out, e_flags);
5060 break;
5062 case EM_AMDGPU:
5063 out = decode_AMDGPU_machine_flags (out, e_flags, filedata);
5064 break;
5066 case EM_CYGNUS_MEP:
5067 out = decode_MeP_machine_flags (out, e_flags);
5068 break;
5070 case EM_PPC:
5071 if (e_flags & EF_PPC_EMB)
5072 out = stpcpy (out, ", emb");
5074 if (e_flags & EF_PPC_RELOCATABLE)
5075 out = stpcpy (out, _(", relocatable"));
5077 if (e_flags & EF_PPC_RELOCATABLE_LIB)
5078 out = stpcpy (out, _(", relocatable-lib"));
5079 break;
5081 case EM_PPC64:
5082 if (e_flags & EF_PPC64_ABI)
5083 out += sprintf (out, ", abiv%d", e_flags & EF_PPC64_ABI);
5084 break;
5086 case EM_V800:
5087 out = decode_V800_machine_flags (out, e_flags);
5088 break;
5090 case EM_V850:
5091 case EM_CYGNUS_V850:
5092 out = decode_V850_machine_flags (out, e_flags);
5093 break;
5095 case EM_M32R:
5096 case EM_CYGNUS_M32R:
5097 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
5098 out = stpcpy (out, ", m32r");
5099 break;
5101 case EM_MIPS:
5102 case EM_MIPS_RS3_LE:
5103 out = decode_MIPS_machine_flags (out, e_flags);
5104 break;
5106 case EM_NDS32:
5107 out = decode_NDS32_machine_flags (out, e_flags);
5108 break;
5110 case EM_NFP:
5111 switch (EF_NFP_MACH (e_flags))
5113 case E_NFP_MACH_3200:
5114 out = stpcpy (out, ", NFP-32xx");
5115 break;
5116 case E_NFP_MACH_6000:
5117 out = stpcpy (out, ", NFP-6xxx");
5118 break;
5120 break;
5122 case EM_RISCV:
5123 out = decode_RISCV_machine_flags (out, e_flags);
5124 break;
5126 case EM_SH:
5127 out = decode_SH_machine_flags (out, e_flags);
5128 break;
5130 case EM_OR1K:
5131 if (e_flags & EF_OR1K_NODELAY)
5132 out = stpcpy (out, ", no delay");
5133 break;
5135 case EM_BPF:
5136 out += sprintf (out, ", CPU Version: %u", e_flags & EF_BPF_CPUVER);
5137 break;
5139 case EM_SPARCV9:
5140 out = decode_SPARC_machine_flags (out, e_flags);
5141 break;
5143 case EM_PARISC:
5144 out = decode_PARISC_machine_flags (out, e_flags);
5145 break;
5147 case EM_PJ:
5148 case EM_PJ_OLD:
5149 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
5150 out = stpcpy (out, ", new calling convention");
5152 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
5153 out = stpcpy (out, ", gnu calling convention");
5154 break;
5156 case EM_IA_64:
5157 out = decode_IA64_machine_flags (out, e_flags, filedata);
5158 break;
5160 case EM_VAX:
5161 if ((e_flags & EF_VAX_NONPIC))
5162 out = stpcpy (out, ", non-PIC");
5163 if ((e_flags & EF_VAX_DFLOAT))
5164 out = stpcpy (out, ", D-Float");
5165 if ((e_flags & EF_VAX_GFLOAT))
5166 out = stpcpy (out, ", G-Float");
5167 break;
5169 case EM_VISIUM:
5170 if (e_flags & EF_VISIUM_ARCH_MCM)
5171 out = stpcpy (out, ", mcm");
5172 else if (e_flags & EF_VISIUM_ARCH_MCM24)
5173 out = stpcpy (out, ", mcm24");
5174 if (e_flags & EF_VISIUM_ARCH_GR6)
5175 out = stpcpy (out, ", gr6");
5176 break;
5178 case EM_RL78:
5179 out = decode_RL78_machine_flags (out, e_flags);
5180 break;
5182 case EM_RX:
5183 out = decode_RX_machine_flags (out, e_flags);
5184 break;
5186 case EM_S390:
5187 if (e_flags & EF_S390_HIGH_GPRS)
5188 out = stpcpy (out, ", highgprs");
5189 break;
5191 case EM_TI_C6000:
5192 if ((e_flags & EF_C6000_REL))
5193 out = stpcpy (out, ", relocatable module");
5194 break;
5196 case EM_KVX:
5197 if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV3_1)
5198 strcat (buf, ", Kalray VLIW kv3-1");
5199 else if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV3_2)
5200 strcat (buf, ", Kalray VLIW kv3-2");
5201 else if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV4_1)
5202 strcat (buf, ", Kalray VLIW kv4-1");
5203 else
5204 strcat (buf, ", unknown KVX MPPA");
5205 break;
5207 case EM_MSP430:
5208 out = decode_MSP430_machine_flags (out, e_flags);
5209 break;
5211 case EM_Z80:
5212 out = decode_Z80_machine_flags (out, e_flags);
5213 break;
5215 case EM_LOONGARCH:
5216 out = decode_LOONGARCH_machine_flags (out, e_flags);
5217 break;
5221 return buf;
5224 static const char *
5225 get_osabi_name (Filedata * filedata, unsigned int osabi)
5227 static char buff[32];
5229 switch (osabi)
5231 case ELFOSABI_NONE: return "UNIX - System V";
5232 case ELFOSABI_HPUX: return "UNIX - HP-UX";
5233 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
5234 case ELFOSABI_GNU: return "UNIX - GNU";
5235 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
5236 case ELFOSABI_AIX: return "UNIX - AIX";
5237 case ELFOSABI_IRIX: return "UNIX - IRIX";
5238 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
5239 case ELFOSABI_TRU64: return "UNIX - TRU64";
5240 case ELFOSABI_MODESTO: return "Novell - Modesto";
5241 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
5242 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
5243 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
5244 case ELFOSABI_AROS: return "AROS";
5245 case ELFOSABI_FENIXOS: return "FenixOS";
5246 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
5247 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
5248 case ELFOSABI_CUDA: return "CUDA";
5249 default:
5250 if (osabi >= 64)
5251 switch (filedata->file_header.e_machine)
5253 case EM_AMDGPU:
5254 switch (osabi)
5256 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
5257 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
5258 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
5259 default:
5260 break;
5262 break;
5264 case EM_ARM:
5265 switch (osabi)
5267 case ELFOSABI_ARM: return "ARM";
5268 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
5269 default:
5270 break;
5272 break;
5274 case EM_MSP430:
5275 case EM_MSP430_OLD:
5276 case EM_VISIUM:
5277 switch (osabi)
5279 case ELFOSABI_STANDALONE: return _("Standalone App");
5280 default:
5281 break;
5283 break;
5285 case EM_TI_C6000:
5286 switch (osabi)
5288 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
5289 case ELFOSABI_C6000_LINUX: return "Linux C6000";
5290 default:
5291 break;
5293 break;
5295 default:
5296 break;
5298 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
5299 return buff;
5303 static const char *
5304 get_aarch64_segment_type (unsigned long type)
5306 switch (type)
5308 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
5309 case PT_AARCH64_MEMTAG_MTE: return "AARCH64_MEMTAG_MTE";
5310 default: return NULL;
5314 static const char *
5315 get_arm_segment_type (unsigned long type)
5317 switch (type)
5319 case PT_ARM_ARCHEXT: return "ARM_ARCHEXT";
5320 case PT_ARM_EXIDX: return "ARM_EXIDX";
5321 default: return NULL;
5325 static const char *
5326 get_s390_segment_type (unsigned long type)
5328 switch (type)
5330 case PT_S390_PGSTE: return "S390_PGSTE";
5331 default: return NULL;
5335 static const char *
5336 get_mips_segment_type (unsigned long type)
5338 switch (type)
5340 case PT_MIPS_REGINFO: return "REGINFO";
5341 case PT_MIPS_RTPROC: return "RTPROC";
5342 case PT_MIPS_OPTIONS: return "OPTIONS";
5343 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
5344 default: return NULL;
5348 static const char *
5349 get_parisc_segment_type (unsigned long type)
5351 switch (type)
5353 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
5354 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
5355 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
5356 default: return NULL;
5360 static const char *
5361 get_ia64_segment_type (unsigned long type)
5363 switch (type)
5365 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
5366 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
5367 default: return NULL;
5371 static const char *
5372 get_tic6x_segment_type (unsigned long type)
5374 switch (type)
5376 case PT_C6000_PHATTR: return "C6000_PHATTR";
5377 default: return NULL;
5381 static const char *
5382 get_riscv_segment_type (unsigned long type)
5384 switch (type)
5386 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5387 default: return NULL;
5391 static const char *
5392 get_hpux_segment_type (unsigned long type, unsigned e_machine)
5394 if (e_machine == EM_PARISC)
5395 switch (type)
5397 case PT_HP_TLS: return "HP_TLS";
5398 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
5399 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
5400 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
5401 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
5402 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
5403 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
5404 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
5405 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
5406 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
5407 case PT_HP_PARALLEL: return "HP_PARALLEL";
5408 case PT_HP_FASTBIND: return "HP_FASTBIND";
5409 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
5410 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
5411 case PT_HP_STACK: return "HP_STACK";
5412 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
5413 default:
5414 break;
5417 if (e_machine == EM_IA_64)
5418 switch (type)
5420 case PT_HP_TLS: return "HP_TLS";
5421 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
5422 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
5423 case PT_IA_64_HP_STACK: return "HP_STACK";
5424 default:
5425 break;
5428 return NULL;
5431 static const char *
5432 get_solaris_segment_type (unsigned long type)
5434 switch (type)
5436 case PT_SUNW_UNWIND: return "SUNW_UNWIND";
5437 case PT_SUNW_EH_FRAME: return "SUNW_EH_FRAME";
5438 case PT_SUNWBSS: return "SUNW_BSS";
5439 case PT_SUNWSTACK: return "SUNW_STACK";
5440 case PT_SUNWDTRACE: return "SUNW_DTRACE";
5441 case PT_SUNWCAP: return "SUNW_CAP";
5442 default: return NULL;
5446 static const char *
5447 get_os_specific_segment_type (Filedata * filedata, unsigned long p_type)
5449 static char buff[32];
5450 const char * result = NULL;
5452 switch (filedata->file_header.e_ident[EI_OSABI])
5454 case ELFOSABI_GNU:
5455 case ELFOSABI_FREEBSD:
5456 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
5458 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
5459 result = buff;
5461 break;
5463 case ELFOSABI_HPUX:
5464 result = get_hpux_segment_type (p_type,
5465 filedata->file_header.e_machine);
5466 break;
5468 case ELFOSABI_SOLARIS:
5469 result = get_solaris_segment_type (p_type);
5470 break;
5472 default:
5473 break;
5476 if (result != NULL)
5477 return result;
5479 switch (p_type)
5481 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
5482 case PT_GNU_STACK: return "GNU_STACK";
5483 case PT_GNU_RELRO: return "GNU_RELRO";
5484 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
5485 case PT_GNU_SFRAME: return "GNU_SFRAME";
5487 case PT_OPENBSD_MUTABLE: return "OPENBSD_MUTABLE";
5488 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
5489 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
5490 case PT_OPENBSD_NOBTCFI: return "OPENBSD_NOBTCFI";
5491 case PT_OPENBSD_SYSCALLS: return "OPENBSD_SYSCALLS";
5492 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
5494 default:
5495 break;
5498 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
5499 return buff;
5502 static const char *
5503 get_processor_specific_segment_type (Filedata * filedata, unsigned long p_type)
5505 static char buff[32];
5506 const char * result = NULL;
5508 switch (filedata->file_header.e_machine)
5510 case EM_AARCH64:
5511 result = get_aarch64_segment_type (p_type);
5512 break;
5514 case EM_ARM:
5515 result = get_arm_segment_type (p_type);
5516 break;
5518 case EM_MIPS:
5519 case EM_MIPS_RS3_LE:
5520 result = get_mips_segment_type (p_type);
5521 break;
5523 case EM_PARISC:
5524 result = get_parisc_segment_type (p_type);
5525 break;
5527 case EM_IA_64:
5528 result = get_ia64_segment_type (p_type);
5529 break;
5531 case EM_TI_C6000:
5532 result = get_tic6x_segment_type (p_type);
5533 break;
5535 case EM_S390:
5536 case EM_S390_OLD:
5537 result = get_s390_segment_type (p_type);
5538 break;
5540 case EM_RISCV:
5541 result = get_riscv_segment_type (p_type);
5542 break;
5544 default:
5545 result = NULL;
5546 break;
5549 if (result != NULL)
5550 return result;
5552 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
5553 return buff;
5556 static const char *
5557 get_segment_type (Filedata * filedata, unsigned long p_type)
5559 static char buff[32];
5561 switch (p_type)
5563 case PT_NULL: return "NULL";
5564 case PT_LOAD: return "LOAD";
5565 case PT_DYNAMIC: return "DYNAMIC";
5566 case PT_INTERP: return "INTERP";
5567 case PT_NOTE: return "NOTE";
5568 case PT_SHLIB: return "SHLIB";
5569 case PT_PHDR: return "PHDR";
5570 case PT_TLS: return "TLS";
5571 case PT_NUM: return "NUM";
5574 if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
5575 return get_os_specific_segment_type (filedata, p_type);
5577 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
5578 return get_processor_specific_segment_type (filedata, p_type);
5580 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
5581 return buff;
5584 static const char *
5585 get_arc_section_type_name (unsigned int sh_type)
5587 switch (sh_type)
5589 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
5590 default:
5591 break;
5593 return NULL;
5596 static const char *
5597 get_mips_section_type_name (unsigned int sh_type)
5599 switch (sh_type)
5601 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
5602 case SHT_MIPS_MSYM: return "MIPS_MSYM";
5603 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
5604 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
5605 case SHT_MIPS_UCODE: return "MIPS_UCODE";
5606 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
5607 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
5608 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
5609 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
5610 case SHT_MIPS_RELD: return "MIPS_RELD";
5611 case SHT_MIPS_IFACE: return "MIPS_IFACE";
5612 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
5613 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
5614 case SHT_MIPS_SHDR: return "MIPS_SHDR";
5615 case SHT_MIPS_FDESC: return "MIPS_FDESC";
5616 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
5617 case SHT_MIPS_DENSE: return "MIPS_DENSE";
5618 case SHT_MIPS_PDESC: return "MIPS_PDESC";
5619 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
5620 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
5621 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
5622 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
5623 case SHT_MIPS_LINE: return "MIPS_LINE";
5624 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
5625 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
5626 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
5627 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
5628 case SHT_MIPS_DWARF: return "MIPS_DWARF";
5629 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
5630 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
5631 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
5632 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
5633 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
5634 case SHT_MIPS_XLATE: return "MIPS_XLATE";
5635 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
5636 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
5637 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
5638 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
5639 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
5640 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
5641 case SHT_MIPS_XHASH: return "MIPS_XHASH";
5642 default:
5643 break;
5645 return NULL;
5648 static const char *
5649 get_parisc_section_type_name (unsigned int sh_type)
5651 switch (sh_type)
5653 case SHT_PARISC_EXT: return "PARISC_EXT";
5654 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
5655 case SHT_PARISC_DOC: return "PARISC_DOC";
5656 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
5657 case SHT_PARISC_DLKM: return "PARISC_DLKM";
5658 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
5659 case SHT_PARISC_STUBS: return "PARISC_STUBS";
5660 default: return NULL;
5664 static const char *
5665 get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
5667 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
5668 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
5669 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
5671 switch (sh_type)
5673 case SHT_IA_64_EXT: return "IA_64_EXT";
5674 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
5675 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
5676 default:
5677 break;
5679 return NULL;
5682 static const char *
5683 get_vms_section_type_name (unsigned int sh_type)
5685 switch (sh_type)
5687 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
5688 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
5689 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
5690 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
5691 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
5692 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
5693 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
5694 default:
5695 break;
5697 return NULL;
5700 static const char *
5701 get_x86_64_section_type_name (unsigned int sh_type)
5703 switch (sh_type)
5705 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
5706 default: return NULL;
5710 static const char *
5711 get_aarch64_section_type_name (unsigned int sh_type)
5713 switch (sh_type)
5715 case SHT_AARCH64_ATTRIBUTES:
5716 return "AARCH64_ATTRIBUTES";
5717 case SHT_AARCH64_AUTH_RELR:
5718 return "AARCH64_AUTH_RELR";
5719 case SHT_AARCH64_MEMTAG_GLOBALS_STATIC:
5720 return "AARCH64_MEMTAG_GLOBALS_STATIC";
5721 case SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC:
5722 return "AARCH64_MEMTAG_GLOBALS_DYNAMIC";
5723 default:
5724 return NULL;
5728 static const char *
5729 get_arm_section_type_name (unsigned int sh_type)
5731 switch (sh_type)
5733 case SHT_ARM_EXIDX: return "ARM_EXIDX";
5734 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
5735 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
5736 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
5737 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
5738 default: return NULL;
5742 static const char *
5743 get_tic6x_section_type_name (unsigned int sh_type)
5745 switch (sh_type)
5747 case SHT_C6000_UNWIND: return "C6000_UNWIND";
5748 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
5749 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
5750 case SHT_TI_ICODE: return "TI_ICODE";
5751 case SHT_TI_XREF: return "TI_XREF";
5752 case SHT_TI_HANDLER: return "TI_HANDLER";
5753 case SHT_TI_INITINFO: return "TI_INITINFO";
5754 case SHT_TI_PHATTRS: return "TI_PHATTRS";
5755 default: return NULL;
5759 static const char *
5760 get_msp430_section_type_name (unsigned int sh_type)
5762 switch (sh_type)
5764 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
5765 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
5766 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
5767 default: return NULL;
5771 static const char *
5772 get_nfp_section_type_name (unsigned int sh_type)
5774 switch (sh_type)
5776 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
5777 case SHT_NFP_INITREG: return "NFP_INITREG";
5778 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
5779 default: return NULL;
5783 static const char *
5784 get_v850_section_type_name (unsigned int sh_type)
5786 switch (sh_type)
5788 case SHT_V850_SCOMMON: return "V850 Small Common";
5789 case SHT_V850_TCOMMON: return "V850 Tiny Common";
5790 case SHT_V850_ZCOMMON: return "V850 Zero Common";
5791 case SHT_RENESAS_IOP: return "RENESAS IOP";
5792 case SHT_RENESAS_INFO: return "RENESAS INFO";
5793 default: return NULL;
5797 static const char *
5798 get_riscv_section_type_name (unsigned int sh_type)
5800 switch (sh_type)
5802 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5803 default: return NULL;
5807 static const char *
5808 get_csky_section_type_name (unsigned int sh_type)
5810 switch (sh_type)
5812 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
5813 default: return NULL;
5817 static const char *
5818 get_powerpc_section_type_name (unsigned int sh_type)
5820 switch (sh_type)
5822 case SHT_ORDERED: return "ORDERED";
5823 default: return NULL;
5827 static const char *
5828 get_alpha_section_type_name (unsigned int sh_type)
5830 switch (sh_type)
5832 case SHT_ALPHA_DEBUG: return "DEBUG";
5833 case SHT_ALPHA_REGINFO: return "REGINFO";
5834 default: return NULL;
5838 static const char *
5839 get_processor_specific_section_type_name (Filedata * filedata, unsigned int sh_type)
5841 static char buff[32];
5842 const char * result = NULL;
5844 switch (filedata->file_header.e_machine)
5846 case EM_AARCH64:
5847 result = get_aarch64_section_type_name (sh_type);
5848 break;
5850 case EM_ALPHA:
5851 result = get_alpha_section_type_name (sh_type);
5852 break;
5854 case EM_ARC:
5855 case EM_ARC_COMPACT:
5856 case EM_ARC_COMPACT2:
5857 case EM_ARC_COMPACT3:
5858 case EM_ARC_COMPACT3_64:
5859 result = get_arc_section_type_name (sh_type);
5860 break;
5862 case EM_ARM:
5863 result = get_arm_section_type_name (sh_type);
5864 break;
5866 case EM_CSKY:
5867 result = get_csky_section_type_name (sh_type);
5868 break;
5870 case EM_IA_64:
5871 result = get_ia64_section_type_name (filedata, sh_type);
5872 break;
5874 case EM_MIPS:
5875 case EM_MIPS_RS3_LE:
5876 result = get_mips_section_type_name (sh_type);
5877 break;
5879 case EM_MSP430:
5880 result = get_msp430_section_type_name (sh_type);
5881 break;
5883 case EM_NFP:
5884 result = get_nfp_section_type_name (sh_type);
5885 break;
5887 case EM_PARISC:
5888 result = get_parisc_section_type_name (sh_type);
5889 break;
5891 case EM_PPC64:
5892 case EM_PPC:
5893 return get_powerpc_section_type_name (sh_type);
5894 break;
5896 case EM_RISCV:
5897 result = get_riscv_section_type_name (sh_type);
5898 break;
5900 case EM_TI_C6000:
5901 result = get_tic6x_section_type_name (sh_type);
5902 break;
5904 case EM_V800:
5905 case EM_V850:
5906 case EM_CYGNUS_V850:
5907 result = get_v850_section_type_name (sh_type);
5908 break;
5910 case EM_X86_64:
5911 case EM_L1OM:
5912 case EM_K1OM:
5913 result = get_x86_64_section_type_name (sh_type);
5914 break;
5916 default:
5917 break;
5920 if (result != NULL)
5921 return result;
5923 switch (sh_type)
5925 /* FIXME: Are these correct ? If so, why do they not have #define's ? */
5926 case 0x7ffffffd: return "AUXILIARY";
5927 case 0x7fffffff: return "FILTER";
5928 default:
5929 break;
5932 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
5933 return buff;
5936 static const char *
5937 get_os_specific_section_type_name (Filedata * filedata, unsigned int sh_type)
5939 static char buff[32];
5940 const char * result = NULL;
5942 switch (filedata->file_header.e_machine)
5944 case EM_IA_64:
5945 result = get_vms_section_type_name (sh_type);
5946 break;
5947 default:
5948 break;
5951 if (result != NULL)
5952 return result;
5954 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
5955 result = get_solaris_section_type (sh_type);
5957 if (result != NULL)
5958 return result;
5960 switch (sh_type)
5962 case SHT_GNU_INCREMENTAL_INPUTS: return "GNU_INCREMENTAL_INPUTS";
5963 case SHT_GNU_ATTRIBUTES: return "GNU_ATTRIBUTES";
5964 case SHT_GNU_HASH: return "GNU_HASH";
5965 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
5966 case SHT_GNU_OBJECT_ONLY: return "GNU_OBJECT_ONLY";
5968 case SHT_SUNW_move: return "SUNW_MOVE";
5969 case SHT_SUNW_COMDAT: return "SUNW_COMDAT";
5970 case SHT_SUNW_syminfo: return "SUNW_SYMINFO";
5971 case SHT_GNU_verdef: return "VERDEF";
5972 case SHT_GNU_verneed: return "VERNEED";
5973 case SHT_GNU_versym: return "VERSYM";
5975 case SHT_LLVM_ODRTAB: return "LLVM_ODRTAB";
5976 case SHT_LLVM_LINKER_OPTIONS: return "LLVM_LINKER_OPTIONS";
5977 case SHT_LLVM_ADDRSIG: return "LLVM_ADDRSIG";
5978 case SHT_LLVM_DEPENDENT_LIBRARIES: return "LLVM_DEPENDENT_LIBRARIES";
5979 case SHT_LLVM_SYMPART: return "LLVM_SYMPART";
5980 case SHT_LLVM_PART_EHDR: return "LLVM_PART_EHDR";
5981 case SHT_LLVM_PART_PHDR: return "LLVM_PART_PHDR";
5982 case SHT_LLVM_BB_ADDR_MAP_V0: return "LLVM_BB_ADDR_MAP_V0";
5983 case SHT_LLVM_CALL_GRAPH_PROFILE: return "LLVM_CALL_GRAPH_PROFILE";
5984 case SHT_LLVM_BB_ADDR_MAP: return "LLVM_BB_ADDR_MAP";
5985 case SHT_LLVM_OFFLOADING: return "LLVM_OFFLOADING";
5986 case SHT_LLVM_LTO: return "LLVM_LTO";
5988 case SHT_ANDROID_REL: return "ANDROID_REL";
5989 case SHT_ANDROID_RELA: return "ANDROID_RELA";
5990 case SHT_ANDROID_RELR: return "ANDROID_RELR";
5992 case SHT_CHECKSUM: return "CHECKSUM";
5994 /* FIXME: Are these correct ? If so, why do they not have #define's ? */
5995 case 0x6ffffff0: return "VERSYM";
5997 default:
5998 break;
6001 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
6002 return buff;
6005 static const char *
6006 get_user_specific_section_type_name (Filedata * filedata, unsigned int sh_type)
6008 static char buff[32];
6009 const char * result;
6011 switch (filedata->file_header.e_machine)
6013 case EM_V800:
6014 case EM_V850:
6015 case EM_CYGNUS_V850:
6016 result = get_v850_section_type_name (sh_type);
6017 break;
6019 default:
6020 result = NULL;
6021 break;
6024 if (result != NULL)
6025 return result;
6027 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
6028 return buff;
6031 static const char *
6032 get_section_type_name (Filedata * filedata,
6033 unsigned int sh_type)
6035 switch (sh_type)
6037 case SHT_NULL: return "NULL";
6038 case SHT_PROGBITS: return "PROGBITS";
6039 case SHT_SYMTAB: return "SYMTAB";
6040 case SHT_STRTAB: return "STRTAB";
6041 case SHT_RELA: return "RELA";
6042 case SHT_HASH: return "HASH";
6043 case SHT_DYNAMIC: return "DYNAMIC";
6044 case SHT_NOTE: return "NOTE";
6045 case SHT_NOBITS: return "NOBITS";
6046 case SHT_REL: return "REL";
6047 case SHT_SHLIB: return "SHLIB";
6048 case SHT_DYNSYM: return "DYNSYM";
6049 /* 12 and 13 are not defined. */
6050 case SHT_INIT_ARRAY: return "INIT_ARRAY";
6051 case SHT_FINI_ARRAY: return "FINI_ARRAY";
6052 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
6053 case SHT_GROUP: return "GROUP";
6054 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
6055 case SHT_RELR: return "RELR";
6056 /* End of generic section types. */
6058 default:
6059 break;
6062 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
6063 return get_processor_specific_section_type_name (filedata, sh_type);
6065 if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
6066 return get_os_specific_section_type_name (filedata, sh_type);
6068 if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
6069 return get_user_specific_section_type_name (filedata, sh_type);
6071 static char buff[32];
6073 /* This message is probably going to be displayed in a 15
6074 character wide field, so put the hex value first. */
6075 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
6076 return buff;
6079 enum long_option_values
6081 OPTION_DEBUG_DUMP = 512,
6082 OPTION_DYN_SYMS,
6083 OPTION_LTO_SYMS,
6084 OPTION_DWARF_DEPTH,
6085 OPTION_DWARF_START,
6086 OPTION_DWARF_CHECK,
6087 OPTION_CTF_DUMP,
6088 OPTION_CTF_PARENT,
6089 OPTION_CTF_SYMBOLS,
6090 OPTION_CTF_STRINGS,
6091 OPTION_SFRAME_DUMP,
6092 OPTION_WITH_SYMBOL_VERSIONS,
6093 OPTION_RECURSE_LIMIT,
6094 OPTION_NO_RECURSE_LIMIT,
6095 OPTION_NO_DEMANGLING,
6096 OPTION_NO_EXTRA_SYM_INFO,
6097 OPTION_SYM_BASE
6100 static struct option options[] =
6102 /* Note - This table is alpha-sorted on the 'val'
6103 field in order to make adding new options easier. */
6104 {"arch-specific", no_argument, 0, 'A'},
6105 {"all", no_argument, 0, 'a'},
6106 {"demangle", optional_argument, 0, 'C'},
6107 {"archive-index", no_argument, 0, 'c'},
6108 {"use-dynamic", no_argument, 0, 'D'},
6109 {"dynamic", no_argument, 0, 'd'},
6110 {"headers", no_argument, 0, 'e'},
6111 {"section-groups", no_argument, 0, 'g'},
6112 {"help", no_argument, 0, 'H'},
6113 {"file-header", no_argument, 0, 'h'},
6114 {"histogram", no_argument, 0, 'I'},
6115 {"display-section", required_argument, 0, 'j'},
6116 {"lint", no_argument, 0, 'L'},
6117 {"enable-checks", no_argument, 0, 'L'},
6118 {"program-headers", no_argument, 0, 'l'},
6119 {"segments", no_argument, 0, 'l'},
6120 {"full-section-name",no_argument, 0, 'N'},
6121 {"notes", no_argument, 0, 'n'},
6122 {"process-links", no_argument, 0, 'P'},
6123 {"string-dump", required_argument, 0, 'p'},
6124 {"relocated-dump", required_argument, 0, 'R'},
6125 {"relocs", no_argument, 0, 'r'},
6126 {"section-headers", no_argument, 0, 'S'},
6127 {"sections", no_argument, 0, 'S'},
6128 {"symbols", no_argument, 0, 's'},
6129 {"syms", no_argument, 0, 's'},
6130 {"silent-truncation",no_argument, 0, 'T'},
6131 {"section-details", no_argument, 0, 't'},
6132 {"unicode", required_argument, NULL, 'U'},
6133 {"unwind", no_argument, 0, 'u'},
6134 {"version-info", no_argument, 0, 'V'},
6135 {"version", no_argument, 0, 'v'},
6136 {"wide", no_argument, 0, 'W'},
6137 {"extra-sym-info", no_argument, 0, 'X'},
6138 {"hex-dump", required_argument, 0, 'x'},
6139 {"decompress", no_argument, 0, 'z'},
6141 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
6142 {"no-extra-sym-info",no_argument, 0, OPTION_NO_EXTRA_SYM_INFO},
6143 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
6144 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
6145 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
6146 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
6147 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
6148 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
6149 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
6150 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
6151 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
6152 #ifdef ENABLE_LIBCTF
6153 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
6154 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
6155 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
6156 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
6157 #endif
6158 {"sframe", optional_argument, 0, OPTION_SFRAME_DUMP},
6159 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
6161 {0, no_argument, 0, 0}
6164 static void
6165 usage (FILE * stream)
6167 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
6168 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
6169 fprintf (stream, _(" Options are:\n"));
6170 fprintf (stream, _("\
6171 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
6172 fprintf (stream, _("\
6173 -h --file-header Display the ELF file header\n"));
6174 fprintf (stream, _("\
6175 -l --program-headers Display the program headers\n"));
6176 fprintf (stream, _("\
6177 --segments An alias for --program-headers\n"));
6178 fprintf (stream, _("\
6179 -S --section-headers Display the sections' header\n"));
6180 fprintf (stream, _("\
6181 --sections An alias for --section-headers\n"));
6182 fprintf (stream, _("\
6183 -g --section-groups Display the section groups\n"));
6184 fprintf (stream, _("\
6185 -t --section-details Display the section details\n"));
6186 fprintf (stream, _("\
6187 -e --headers Equivalent to: -h -l -S\n"));
6188 fprintf (stream, _("\
6189 -s --syms Display the symbol table\n"));
6190 fprintf (stream, _("\
6191 --symbols An alias for --syms\n"));
6192 fprintf (stream, _("\
6193 --dyn-syms Display the dynamic symbol table\n"));
6194 fprintf (stream, _("\
6195 --lto-syms Display LTO symbol tables\n"));
6196 fprintf (stream, _("\
6197 --sym-base=[0|8|10|16] \n\
6198 Force base for symbol sizes. The options are \n\
6199 mixed (the default), octal, decimal, hexadecimal.\n"));
6200 fprintf (stream, _("\
6201 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
6202 display_demangler_styles (stream, _("\
6203 STYLE can be "));
6204 fprintf (stream, _("\
6205 --no-demangle Do not demangle low-level symbol names. (default)\n"));
6206 fprintf (stream, _("\
6207 --recurse-limit Enable a demangling recursion limit. (default)\n"));
6208 fprintf (stream, _("\
6209 --no-recurse-limit Disable a demangling recursion limit\n"));
6210 fprintf (stream, _("\
6211 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
6212 Display unicode characters as determined by the current locale\n\
6213 (default), escape sequences, \"<hex sequences>\", highlighted\n\
6214 escape sequences, or treat them as invalid and display as\n\
6215 \"{hex sequences}\"\n"));
6216 fprintf (stream, _("\
6217 -X --extra-sym-info Display extra information when showing symbols\n"));
6218 fprintf (stream, _("\
6219 --no-extra-sym-info Do not display extra information when showing symbols (default)\n"));
6220 fprintf (stream, _("\
6221 -n --notes Display the contents of note sections (if present)\n"));
6222 fprintf (stream, _("\
6223 -r --relocs Display the relocations (if present)\n"));
6224 fprintf (stream, _("\
6225 -u --unwind Display the unwind info (if present)\n"));
6226 fprintf (stream, _("\
6227 -d --dynamic Display the dynamic section (if present)\n"));
6228 fprintf (stream, _("\
6229 -V --version-info Display the version sections (if present)\n"));
6230 fprintf (stream, _("\
6231 -A --arch-specific Display architecture specific information (if any)\n"));
6232 fprintf (stream, _("\
6233 -c --archive-index Display the symbol/file index in an archive\n"));
6234 fprintf (stream, _("\
6235 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
6236 fprintf (stream, _("\
6237 -L --lint|--enable-checks\n\
6238 Display warning messages for possible problems\n"));
6239 fprintf (stream, _("\
6240 -x --hex-dump=<number|name>\n\
6241 Dump the contents of section <number|name> as bytes\n"));
6242 fprintf (stream, _("\
6243 -p --string-dump=<number|name>\n\
6244 Dump the contents of section <number|name> as strings\n"));
6245 fprintf (stream, _("\
6246 -R --relocated-dump=<number|name>\n\
6247 Dump the relocated contents of section <number|name>\n"));
6248 fprintf (stream, _("\
6249 -z --decompress Decompress section before dumping it\n"));
6250 fprintf (stream, _("\n\
6251 -j --display-section=<name|number>\n\
6252 Display the contents of the indicated section. Can be repeated\n"));
6253 fprintf (stream, _("\
6254 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
6255 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
6256 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
6257 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
6258 U/=trace_info]\n\
6259 Display the contents of DWARF debug sections\n"));
6260 fprintf (stream, _("\
6261 -wk --debug-dump=links Display the contents of sections that link to separate\n\
6262 debuginfo files\n"));
6263 fprintf (stream, _("\
6264 -P --process-links Display the contents of non-debug sections in separate\n\
6265 debuginfo files. (Implies -wK)\n"));
6266 #if DEFAULT_FOR_FOLLOW_LINKS
6267 fprintf (stream, _("\
6268 -wK --debug-dump=follow-links\n\
6269 Follow links to separate debug info files (default)\n"));
6270 fprintf (stream, _("\
6271 -wN --debug-dump=no-follow-links\n\
6272 Do not follow links to separate debug info files\n"));
6273 #else
6274 fprintf (stream, _("\
6275 -wK --debug-dump=follow-links\n\
6276 Follow links to separate debug info files\n"));
6277 fprintf (stream, _("\
6278 -wN --debug-dump=no-follow-links\n\
6279 Do not follow links to separate debug info files\n\
6280 (default)\n"));
6281 #endif
6282 #if HAVE_LIBDEBUGINFOD
6283 fprintf (stream, _("\
6284 -wD --debug-dump=use-debuginfod\n\
6285 When following links, also query debuginfod servers (default)\n"));
6286 fprintf (stream, _("\
6287 -wE --debug-dump=do-not-use-debuginfod\n\
6288 When following links, do not query debuginfod servers\n"));
6289 #endif
6290 fprintf (stream, _("\
6291 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
6292 fprintf (stream, _("\
6293 --dwarf-start=N Display DIEs starting at offset N\n"));
6294 #ifdef ENABLE_LIBCTF
6295 fprintf (stream, _("\
6296 --ctf=<number|name> Display CTF info from section <number|name>\n"));
6297 fprintf (stream, _("\
6298 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
6299 fprintf (stream, _("\
6300 --ctf-symbols=<number|name>\n\
6301 Use section <number|name> as the CTF external symtab\n"));
6302 fprintf (stream, _("\
6303 --ctf-strings=<number|name>\n\
6304 Use section <number|name> as the CTF external strtab\n"));
6305 #endif
6306 fprintf (stream, _("\
6307 --sframe[=NAME] Display SFrame info from section NAME, (default '.sframe')\n"));
6309 #ifdef SUPPORT_DISASSEMBLY
6310 fprintf (stream, _("\
6311 -i --instruction-dump=<number|name>\n\
6312 Disassemble the contents of section <number|name>\n"));
6313 #endif
6314 fprintf (stream, _("\
6315 -I --histogram Display histogram of bucket list lengths\n"));
6316 fprintf (stream, _("\
6317 -W --wide Allow output width to exceed 80 characters\n"));
6318 fprintf (stream, _("\
6319 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
6320 fprintf (stream, _("\
6321 @<file> Read options from <file>\n"));
6322 fprintf (stream, _("\
6323 -H --help Display this information\n"));
6324 fprintf (stream, _("\
6325 -v --version Display the version number of readelf\n"));
6327 if (REPORT_BUGS_TO[0] && stream == stdout)
6328 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
6330 exit (stream == stdout ? 0 : 1);
6333 /* Record the fact that the user wants the contents of section number
6334 SECTION to be displayed using the method(s) encoded as flags bits
6335 in TYPE. Note, TYPE can be zero if we are creating the array for
6336 the first time. */
6338 static void
6339 request_dump_bynumber (struct dump_data *dumpdata,
6340 unsigned int section, dump_type type)
6342 if (section >= dumpdata->num_dump_sects)
6344 dump_type * new_dump_sects;
6346 new_dump_sects = (dump_type *) calloc (section + 1,
6347 sizeof (* new_dump_sects));
6349 if (new_dump_sects == NULL)
6350 error (_("Out of memory allocating dump request table.\n"));
6351 else
6353 if (dumpdata->dump_sects)
6355 /* Copy current flag settings. */
6356 memcpy (new_dump_sects, dumpdata->dump_sects,
6357 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
6359 free (dumpdata->dump_sects);
6362 dumpdata->dump_sects = new_dump_sects;
6363 dumpdata->num_dump_sects = section + 1;
6367 if (dumpdata->dump_sects)
6368 dumpdata->dump_sects[section] |= type;
6371 /* Request a dump by section name. */
6373 static void
6374 request_dump_byname (const char * section, dump_type type)
6376 struct dump_list_entry * new_request;
6378 new_request = (struct dump_list_entry *)
6379 malloc (sizeof (struct dump_list_entry));
6380 if (!new_request)
6381 error (_("Out of memory allocating dump request table.\n"));
6383 new_request->name = strdup (section);
6384 if (!new_request->name)
6385 error (_("Out of memory allocating dump request table.\n"));
6387 new_request->type = type;
6389 new_request->next = dump_sects_byname;
6390 dump_sects_byname = new_request;
6393 static inline void
6394 request_dump (struct dump_data *dumpdata, dump_type type)
6396 int section;
6397 char * cp;
6399 do_dump = true;
6400 section = strtoul (optarg, & cp, 0);
6402 if (! *cp && section >= 0)
6403 request_dump_bynumber (dumpdata, section, type);
6404 else
6405 request_dump_byname (optarg, type);
6408 static void
6409 parse_args (struct dump_data *dumpdata, int argc, char ** argv)
6411 int c;
6413 if (argc < 2)
6414 usage (stderr);
6416 while ((c = getopt_long
6417 (argc, argv, "ACDHILNPR:STU:VWXacdeghi:j:lnp:rstuvw::x:z", options, NULL)) != EOF)
6419 switch (c)
6421 case 0:
6422 /* Long options. */
6423 break;
6424 case 'H':
6425 usage (stdout);
6426 break;
6428 case 'a':
6429 do_syms = true;
6430 do_reloc = true;
6431 do_unwind = true;
6432 do_dynamic = true;
6433 do_header = true;
6434 do_sections = true;
6435 do_section_groups = true;
6436 do_segments = true;
6437 do_version = true;
6438 do_histogram = true;
6439 do_arch = true;
6440 do_notes = true;
6441 break;
6443 case 'g':
6444 do_section_groups = true;
6445 break;
6446 case 't':
6447 case 'N':
6448 do_sections = true;
6449 do_section_details = true;
6450 break;
6451 case 'e':
6452 do_header = true;
6453 do_sections = true;
6454 do_segments = true;
6455 break;
6456 case 'A':
6457 do_arch = true;
6458 break;
6459 case 'D':
6460 do_using_dynamic = true;
6461 break;
6462 case 'r':
6463 do_reloc = true;
6464 break;
6465 case 'u':
6466 do_unwind = true;
6467 break;
6468 case 'h':
6469 do_header = true;
6470 break;
6471 case 'l':
6472 do_segments = true;
6473 break;
6474 case 's':
6475 do_syms = true;
6476 break;
6477 case 'S':
6478 do_sections = true;
6479 break;
6480 case 'd':
6481 do_dynamic = true;
6482 break;
6483 case 'I':
6484 do_histogram = true;
6485 break;
6486 case 'n':
6487 do_notes = true;
6488 break;
6489 case 'c':
6490 do_archive_index = true;
6491 break;
6492 case 'L':
6493 do_checks = true;
6494 break;
6495 case 'P':
6496 process_links = true;
6497 do_follow_links = true;
6498 dump_any_debugging = true;
6499 break;
6500 case 'j':
6501 request_dump (dumpdata, AUTO_DUMP);
6502 break;
6503 case 'x':
6504 request_dump (dumpdata, HEX_DUMP);
6505 break;
6506 case 'p':
6507 request_dump (dumpdata, STRING_DUMP);
6508 break;
6509 case 'R':
6510 request_dump (dumpdata, RELOC_DUMP);
6511 break;
6512 case 'z':
6513 decompress_dumps = true;
6514 break;
6515 case 'w':
6516 if (optarg == NULL)
6518 do_debugging = true;
6519 do_dump = true;
6520 dump_any_debugging = true;
6521 dwarf_select_sections_all ();
6523 else
6525 do_debugging = false;
6526 if (dwarf_select_sections_by_letters (optarg))
6528 do_dump = true;
6529 dump_any_debugging = true;
6532 break;
6533 case OPTION_DEBUG_DUMP:
6534 if (optarg == NULL)
6536 do_dump = true;
6537 do_debugging = true;
6538 dump_any_debugging = true;
6539 dwarf_select_sections_all ();
6541 else
6543 do_debugging = false;
6544 if (dwarf_select_sections_by_names (optarg))
6546 do_dump = true;
6547 dump_any_debugging = true;
6550 break;
6551 case OPTION_DWARF_DEPTH:
6553 char *cp;
6555 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
6557 break;
6558 case OPTION_DWARF_START:
6560 char *cp;
6562 dwarf_start_die = strtoul (optarg, & cp, 0);
6564 break;
6565 case OPTION_DWARF_CHECK:
6566 dwarf_check = true;
6567 break;
6568 case OPTION_CTF_DUMP:
6569 do_ctf = true;
6570 request_dump (dumpdata, CTF_DUMP);
6571 break;
6572 case OPTION_CTF_SYMBOLS:
6573 free (dump_ctf_symtab_name);
6574 dump_ctf_symtab_name = strdup (optarg);
6575 break;
6576 case OPTION_CTF_STRINGS:
6577 free (dump_ctf_strtab_name);
6578 dump_ctf_strtab_name = strdup (optarg);
6579 break;
6580 case OPTION_CTF_PARENT:
6581 free (dump_ctf_parent_name);
6582 dump_ctf_parent_name = strdup (optarg);
6583 break;
6584 case OPTION_SFRAME_DUMP:
6585 do_sframe = true;
6586 /* Providing section name is optional. request_dump (), however,
6587 thrives on non NULL optarg. Handle it explicitly here. */
6588 if (optarg != NULL)
6589 request_dump (dumpdata, SFRAME_DUMP);
6590 else
6592 do_dump = true;
6593 const char *sframe_sec_name = strdup (".sframe");
6594 request_dump_byname (sframe_sec_name, SFRAME_DUMP);
6596 break;
6597 case OPTION_DYN_SYMS:
6598 do_dyn_syms = true;
6599 break;
6600 case OPTION_LTO_SYMS:
6601 do_lto_syms = true;
6602 break;
6603 case 'X':
6604 extra_sym_info = true;
6605 break;
6606 case OPTION_NO_EXTRA_SYM_INFO:
6607 extra_sym_info = false;
6608 break;
6610 #ifdef SUPPORT_DISASSEMBLY
6611 case 'i':
6612 request_dump (dumpdata, DISASS_DUMP);
6613 break;
6614 #endif
6615 case 'v':
6616 print_version (program_name);
6617 break;
6618 case 'V':
6619 do_version = true;
6620 break;
6621 case 'W':
6622 do_wide = true;
6623 break;
6624 case 'T':
6625 do_not_show_symbol_truncation = true;
6626 break;
6627 case 'C':
6628 do_demangle = true;
6629 if (optarg != NULL)
6631 enum demangling_styles style;
6633 style = cplus_demangle_name_to_style (optarg);
6634 if (style == unknown_demangling)
6635 error (_("unknown demangling style `%s'"), optarg);
6637 cplus_demangle_set_style (style);
6639 break;
6640 case OPTION_NO_DEMANGLING:
6641 do_demangle = false;
6642 break;
6643 case OPTION_RECURSE_LIMIT:
6644 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
6645 break;
6646 case OPTION_NO_RECURSE_LIMIT:
6647 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
6648 break;
6649 case OPTION_WITH_SYMBOL_VERSIONS:
6650 /* Ignored for backward compatibility. */
6651 break;
6653 case 'U':
6654 if (optarg == NULL)
6655 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
6656 else if (streq (optarg, "default") || streq (optarg, "d"))
6657 unicode_display = unicode_default;
6658 else if (streq (optarg, "locale") || streq (optarg, "l"))
6659 unicode_display = unicode_locale;
6660 else if (streq (optarg, "escape") || streq (optarg, "e"))
6661 unicode_display = unicode_escape;
6662 else if (streq (optarg, "invalid") || streq (optarg, "i"))
6663 unicode_display = unicode_invalid;
6664 else if (streq (optarg, "hex") || streq (optarg, "x"))
6665 unicode_display = unicode_hex;
6666 else if (streq (optarg, "highlight") || streq (optarg, "h"))
6667 unicode_display = unicode_highlight;
6668 else
6669 error (_("invalid argument to -U/--unicode: %s"), optarg);
6670 break;
6672 case OPTION_SYM_BASE:
6673 sym_base = 0;
6674 if (optarg != NULL)
6676 sym_base = strtoul (optarg, NULL, 0);
6677 switch (sym_base)
6679 case 0:
6680 case 8:
6681 case 10:
6682 case 16:
6683 break;
6685 default:
6686 sym_base = 0;
6687 break;
6690 break;
6692 default:
6693 /* xgettext:c-format */
6694 error (_("Invalid option '-%c'\n"), c);
6695 /* Fall through. */
6696 case '?':
6697 usage (stderr);
6701 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
6702 && !do_segments && !do_header && !do_dump && !do_version
6703 && !do_histogram && !do_debugging && !do_arch && !do_notes
6704 && !do_section_groups && !do_archive_index
6705 && !do_dyn_syms && !do_lto_syms)
6707 if (do_checks)
6709 check_all = true;
6710 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
6711 do_segments = do_header = do_dump = do_version = true;
6712 do_histogram = do_debugging = do_arch = do_notes = true;
6713 do_section_groups = do_archive_index = do_dyn_syms = true;
6714 do_lto_syms = true;
6716 else
6717 usage (stderr);
6721 static const char *
6722 get_elf_class (unsigned int elf_class)
6724 static char buff[32];
6726 switch (elf_class)
6728 case ELFCLASSNONE: return _("none");
6729 case ELFCLASS32: return "ELF32";
6730 case ELFCLASS64: return "ELF64";
6731 default:
6732 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
6733 return buff;
6737 static const char *
6738 get_data_encoding (unsigned int encoding)
6740 static char buff[32];
6742 switch (encoding)
6744 case ELFDATANONE: return _("none");
6745 case ELFDATA2LSB: return _("2's complement, little endian");
6746 case ELFDATA2MSB: return _("2's complement, big endian");
6747 default:
6748 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
6749 return buff;
6753 static bool
6754 check_magic_number (Filedata * filedata, Elf_Internal_Ehdr * header)
6756 if (header->e_ident[EI_MAG0] == ELFMAG0
6757 && header->e_ident[EI_MAG1] == ELFMAG1
6758 && header->e_ident[EI_MAG2] == ELFMAG2
6759 && header->e_ident[EI_MAG3] == ELFMAG3)
6760 return true;
6762 /* Some compilers produce object files that are not in the ELF file format.
6763 As an aid to users of readelf, try to identify these cases and suggest
6764 alternative tools.
6766 FIXME: It is not clear if all four bytes are used as constant magic
6767 valus by all compilers. It may be necessary to recode this function if
6768 different tools use different length sequences. */
6770 static struct
6772 unsigned char magic[4];
6773 const char * obj_message;
6774 const char * ar_message;
6776 known_magic[] =
6778 { { 'B', 'C', 0xc0, 0xde },
6779 N_("This is a LLVM bitcode file - try using llvm-bcanalyzer\n"),
6780 N_("This is a LLVM bitcode file - try extracting and then using llvm-bcanalyzer\n")
6782 { { 'g', 'o', ' ', 'o' },
6783 N_("This is a GO binary file - try using 'go tool objdump' or 'go tool nm'\n"),
6784 NULL
6787 int i;
6789 for (i = ARRAY_SIZE (known_magic); i--;)
6791 if (header->e_ident[EI_MAG0] == known_magic[i].magic[0]
6792 && header->e_ident[EI_MAG1] == known_magic[i].magic[1]
6793 && header->e_ident[EI_MAG2] == known_magic[i].magic[2]
6794 && header->e_ident[EI_MAG3] == known_magic[i].magic[3])
6796 /* Some compiler's analyzer tools do not handle archives,
6797 so we provide two different kinds of error message. */
6798 if (filedata->archive_file_size > 0
6799 && known_magic[i].ar_message != NULL)
6800 error ("%s", known_magic[i].ar_message);
6801 else
6802 error ("%s", known_magic[i].obj_message);
6803 return false;
6807 error (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
6808 return false;
6811 /* Decode the data held in 'filedata->file_header'. */
6813 static bool
6814 process_file_header (Filedata * filedata)
6816 Elf_Internal_Ehdr * header = & filedata->file_header;
6818 if (! check_magic_number (filedata, header))
6819 return false;
6821 if (! filedata->is_separate)
6822 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
6824 if (do_header)
6826 unsigned i;
6828 if (filedata->is_separate)
6829 printf (_("ELF Header in linked file '%s':\n"),
6830 printable_string (filedata->file_name, 0));
6831 else
6832 printf (_("ELF Header:\n"));
6833 printf (_(" Magic: "));
6834 for (i = 0; i < EI_NIDENT; i++)
6835 printf ("%2.2x ", header->e_ident[i]);
6836 printf ("\n");
6837 printf (_(" Class: %s\n"),
6838 get_elf_class (header->e_ident[EI_CLASS]));
6839 printf (_(" Data: %s\n"),
6840 get_data_encoding (header->e_ident[EI_DATA]));
6841 printf (_(" Version: %d%s\n"),
6842 header->e_ident[EI_VERSION],
6843 (header->e_ident[EI_VERSION] == EV_CURRENT
6844 ? _(" (current)")
6845 : (header->e_ident[EI_VERSION] != EV_NONE
6846 ? _(" <unknown>")
6847 : "")));
6848 printf (_(" OS/ABI: %s\n"),
6849 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
6850 printf (_(" ABI Version: %d\n"),
6851 header->e_ident[EI_ABIVERSION]);
6852 printf (_(" Type: %s\n"),
6853 get_file_type (filedata));
6854 printf (_(" Machine: %s\n"),
6855 get_machine_name (header->e_machine));
6856 printf (_(" Version: 0x%lx\n"),
6857 header->e_version);
6859 printf (_(" Entry point address: "));
6860 print_vma (header->e_entry, PREFIX_HEX);
6861 printf (_("\n Start of program headers: "));
6862 print_vma (header->e_phoff, DEC);
6863 printf (_(" (bytes into file)\n Start of section headers: "));
6864 print_vma (header->e_shoff, DEC);
6865 printf (_(" (bytes into file)\n"));
6867 printf (_(" Flags: 0x%lx%s\n"),
6868 header->e_flags,
6869 get_machine_flags (filedata, header->e_flags, header->e_machine));
6870 printf (_(" Size of this header: %u (bytes)\n"),
6871 header->e_ehsize);
6872 printf (_(" Size of program headers: %u (bytes)\n"),
6873 header->e_phentsize);
6874 printf (_(" Number of program headers: %u"),
6875 header->e_phnum);
6876 if (filedata->section_headers != NULL
6877 && header->e_phnum == PN_XNUM
6878 && filedata->section_headers[0].sh_info != 0)
6879 printf (" (%u)", filedata->section_headers[0].sh_info);
6880 putc ('\n', stdout);
6881 printf (_(" Size of section headers: %u (bytes)\n"),
6882 header->e_shentsize);
6883 printf (_(" Number of section headers: %u"),
6884 header->e_shnum);
6885 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
6887 header->e_shnum = filedata->section_headers[0].sh_size;
6888 printf (" (%u)", header->e_shnum);
6890 putc ('\n', stdout);
6891 printf (_(" Section header string table index: %u"),
6892 header->e_shstrndx);
6893 if (filedata->section_headers != NULL
6894 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
6896 header->e_shstrndx = filedata->section_headers[0].sh_link;
6897 printf (" (%u)", header->e_shstrndx);
6899 if (header->e_shstrndx != SHN_UNDEF
6900 && header->e_shstrndx >= header->e_shnum)
6902 header->e_shstrndx = SHN_UNDEF;
6903 printf (_(" <corrupt: out of range>"));
6905 putc ('\n', stdout);
6908 if (filedata->section_headers != NULL)
6910 if (header->e_phnum == PN_XNUM
6911 && filedata->section_headers[0].sh_info != 0)
6913 /* Throw away any cached read of PN_XNUM headers. */
6914 free (filedata->program_headers);
6915 filedata->program_headers = NULL;
6916 header->e_phnum = filedata->section_headers[0].sh_info;
6918 if (header->e_shnum == SHN_UNDEF)
6919 header->e_shnum = filedata->section_headers[0].sh_size;
6920 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
6921 header->e_shstrndx = filedata->section_headers[0].sh_link;
6922 if (header->e_shstrndx >= header->e_shnum)
6923 header->e_shstrndx = SHN_UNDEF;
6926 return true;
6929 /* Read in the program headers from FILEDATA and store them in PHEADERS.
6930 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
6932 static bool
6933 get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
6935 Elf32_External_Phdr * phdrs;
6936 Elf32_External_Phdr * external;
6937 Elf_Internal_Phdr * internal;
6938 unsigned int i;
6939 unsigned int size = filedata->file_header.e_phentsize;
6940 unsigned int num = filedata->file_header.e_phnum;
6942 /* PR binutils/17531: Cope with unexpected section header sizes. */
6943 if (size == 0 || num == 0)
6944 return false;
6945 if (size < sizeof * phdrs)
6947 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
6948 return false;
6950 if (size > sizeof * phdrs)
6951 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
6953 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
6954 size, num, _("program headers"));
6955 if (phdrs == NULL)
6956 return false;
6958 for (i = 0, internal = pheaders, external = phdrs;
6959 i < filedata->file_header.e_phnum;
6960 i++, internal++, external++)
6962 internal->p_type = BYTE_GET (external->p_type);
6963 internal->p_offset = BYTE_GET (external->p_offset);
6964 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6965 internal->p_paddr = BYTE_GET (external->p_paddr);
6966 internal->p_filesz = BYTE_GET (external->p_filesz);
6967 internal->p_memsz = BYTE_GET (external->p_memsz);
6968 internal->p_flags = BYTE_GET (external->p_flags);
6969 internal->p_align = BYTE_GET (external->p_align);
6972 free (phdrs);
6973 return true;
6976 /* Read in the program headers from FILEDATA and store them in PHEADERS.
6977 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
6979 static bool
6980 get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
6982 Elf64_External_Phdr * phdrs;
6983 Elf64_External_Phdr * external;
6984 Elf_Internal_Phdr * internal;
6985 unsigned int i;
6986 unsigned int size = filedata->file_header.e_phentsize;
6987 unsigned int num = filedata->file_header.e_phnum;
6989 /* PR binutils/17531: Cope with unexpected section header sizes. */
6990 if (size == 0 || num == 0)
6991 return false;
6992 if (size < sizeof * phdrs)
6994 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
6995 return false;
6997 if (size > sizeof * phdrs)
6998 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
7000 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
7001 size, num, _("program headers"));
7002 if (!phdrs)
7003 return false;
7005 for (i = 0, internal = pheaders, external = phdrs;
7006 i < filedata->file_header.e_phnum;
7007 i++, internal++, external++)
7009 internal->p_type = BYTE_GET (external->p_type);
7010 internal->p_flags = BYTE_GET (external->p_flags);
7011 internal->p_offset = BYTE_GET (external->p_offset);
7012 internal->p_vaddr = BYTE_GET (external->p_vaddr);
7013 internal->p_paddr = BYTE_GET (external->p_paddr);
7014 internal->p_filesz = BYTE_GET (external->p_filesz);
7015 internal->p_memsz = BYTE_GET (external->p_memsz);
7016 internal->p_align = BYTE_GET (external->p_align);
7019 free (phdrs);
7020 return true;
7023 /* Returns TRUE if the program headers were read into `program_headers'. */
7025 static bool
7026 get_program_headers (Filedata * filedata)
7028 Elf_Internal_Phdr * phdrs;
7030 /* Check cache of prior read. */
7031 if (filedata->program_headers != NULL)
7032 return true;
7034 /* Be kind to memory checkers by looking for
7035 e_phnum values which we know must be invalid. */
7036 if (filedata->file_header.e_phnum
7037 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
7038 >= filedata->file_size)
7040 error (_("Too many program headers - %#x - the file is not that big\n"),
7041 filedata->file_header.e_phnum);
7042 return false;
7045 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
7046 sizeof (Elf_Internal_Phdr));
7047 if (phdrs == NULL)
7049 error (_("Out of memory reading %u program headers\n"),
7050 filedata->file_header.e_phnum);
7051 return false;
7054 if (is_32bit_elf
7055 ? get_32bit_program_headers (filedata, phdrs)
7056 : get_64bit_program_headers (filedata, phdrs))
7058 filedata->program_headers = phdrs;
7059 return true;
7062 free (phdrs);
7063 return false;
7066 /* Print program header info and locate dynamic section. */
7068 static void
7069 process_program_headers (Filedata * filedata)
7071 Elf_Internal_Phdr * segment;
7072 unsigned int i;
7073 Elf_Internal_Phdr * previous_load = NULL;
7075 if (filedata->file_header.e_phnum == 0)
7077 /* PR binutils/12467. */
7078 if (filedata->file_header.e_phoff != 0)
7079 warn (_("possibly corrupt ELF header - it has a non-zero program"
7080 " header offset, but no program headers\n"));
7081 else if (do_segments)
7083 if (filedata->is_separate)
7084 printf (_("\nThere are no program headers in linked file '%s'.\n"),
7085 printable_string (filedata->file_name, 0));
7086 else
7087 printf (_("\nThere are no program headers in this file.\n"));
7089 goto no_headers;
7092 if (do_segments && !do_header)
7094 if (filedata->is_separate)
7095 printf ("\nIn linked file '%s' the ELF file type is %s\n",
7096 printable_string (filedata->file_name, 0),
7097 get_file_type (filedata));
7098 else
7099 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
7100 printf (_("Entry point 0x%" PRIx64 "\n"),
7101 filedata->file_header.e_entry);
7102 printf (ngettext ("There is %d program header,"
7103 " starting at offset %" PRIu64 "\n",
7104 "There are %d program headers,"
7105 " starting at offset %" PRIu64 "\n",
7106 filedata->file_header.e_phnum),
7107 filedata->file_header.e_phnum,
7108 filedata->file_header.e_phoff);
7111 if (! get_program_headers (filedata))
7112 goto no_headers;
7114 if (do_segments)
7116 if (filedata->file_header.e_phnum > 1)
7117 printf (_("\nProgram Headers:\n"));
7118 else
7119 printf (_("\nProgram Headers:\n"));
7121 if (is_32bit_elf)
7122 printf
7123 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
7124 else if (do_wide)
7125 printf
7126 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
7127 else
7129 printf
7130 (_(" Type Offset VirtAddr PhysAddr\n"));
7131 printf
7132 (_(" FileSiz MemSiz Flags Align\n"));
7136 uint64_t dynamic_addr = 0;
7137 uint64_t dynamic_size = 0;
7138 for (i = 0, segment = filedata->program_headers;
7139 i < filedata->file_header.e_phnum;
7140 i++, segment++)
7142 if (do_segments)
7144 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
7146 if (is_32bit_elf)
7148 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
7149 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
7150 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
7151 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
7152 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
7153 printf ("%c%c%c ",
7154 (segment->p_flags & PF_R ? 'R' : ' '),
7155 (segment->p_flags & PF_W ? 'W' : ' '),
7156 (segment->p_flags & PF_X ? 'E' : ' '));
7157 printf ("%#lx", (unsigned long) segment->p_align);
7159 else if (do_wide)
7161 if ((unsigned long) segment->p_offset == segment->p_offset)
7162 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
7163 else
7165 print_vma (segment->p_offset, FULL_HEX);
7166 putchar (' ');
7169 print_vma (segment->p_vaddr, FULL_HEX);
7170 putchar (' ');
7171 print_vma (segment->p_paddr, FULL_HEX);
7172 putchar (' ');
7174 if ((unsigned long) segment->p_filesz == segment->p_filesz)
7175 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
7176 else
7178 print_vma (segment->p_filesz, FULL_HEX);
7179 putchar (' ');
7182 if ((unsigned long) segment->p_memsz == segment->p_memsz)
7183 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
7184 else
7186 print_vma (segment->p_memsz, FULL_HEX);
7189 printf (" %c%c%c ",
7190 (segment->p_flags & PF_R ? 'R' : ' '),
7191 (segment->p_flags & PF_W ? 'W' : ' '),
7192 (segment->p_flags & PF_X ? 'E' : ' '));
7194 if ((unsigned long) segment->p_align == segment->p_align)
7195 printf ("%#lx", (unsigned long) segment->p_align);
7196 else
7198 print_vma (segment->p_align, PREFIX_HEX);
7201 else
7203 print_vma (segment->p_offset, FULL_HEX);
7204 putchar (' ');
7205 print_vma (segment->p_vaddr, FULL_HEX);
7206 putchar (' ');
7207 print_vma (segment->p_paddr, FULL_HEX);
7208 printf ("\n ");
7209 print_vma (segment->p_filesz, FULL_HEX);
7210 putchar (' ');
7211 print_vma (segment->p_memsz, FULL_HEX);
7212 printf (" %c%c%c ",
7213 (segment->p_flags & PF_R ? 'R' : ' '),
7214 (segment->p_flags & PF_W ? 'W' : ' '),
7215 (segment->p_flags & PF_X ? 'E' : ' '));
7216 print_vma (segment->p_align, PREFIX_HEX);
7219 putc ('\n', stdout);
7222 switch (segment->p_type)
7224 case PT_LOAD:
7225 #if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
7226 required by the ELF standard, several programs, including the Linux
7227 kernel, make use of non-ordered segments. */
7228 if (previous_load
7229 && previous_load->p_vaddr > segment->p_vaddr)
7230 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
7231 #endif
7232 if (segment->p_memsz < segment->p_filesz)
7233 error (_("the segment's file size is larger than its memory size\n"));
7234 previous_load = segment;
7235 break;
7237 case PT_PHDR:
7238 /* PR 20815 - Verify that the program header is loaded into memory. */
7239 if (i > 0 && previous_load != NULL)
7240 error (_("the PHDR segment must occur before any LOAD segment\n"));
7241 if (filedata->file_header.e_machine != EM_PARISC)
7243 unsigned int j;
7245 for (j = 1; j < filedata->file_header.e_phnum; j++)
7247 Elf_Internal_Phdr *load = filedata->program_headers + j;
7248 if (load->p_type == PT_LOAD
7249 && load->p_offset <= segment->p_offset
7250 && (load->p_offset + load->p_filesz
7251 >= segment->p_offset + segment->p_filesz)
7252 && load->p_vaddr <= segment->p_vaddr
7253 && (load->p_vaddr + load->p_filesz
7254 >= segment->p_vaddr + segment->p_filesz))
7255 break;
7257 if (j == filedata->file_header.e_phnum)
7258 error (_("the PHDR segment is not covered by a LOAD segment\n"));
7260 break;
7262 case PT_DYNAMIC:
7263 if (dynamic_addr)
7264 error (_("more than one dynamic segment\n"));
7266 /* By default, assume that the .dynamic section is the first
7267 section in the DYNAMIC segment. */
7268 dynamic_addr = segment->p_offset;
7269 dynamic_size = segment->p_filesz;
7271 /* Try to locate the .dynamic section. If there is
7272 a section header table, we can easily locate it. */
7273 if (filedata->section_headers != NULL)
7275 Elf_Internal_Shdr * sec;
7277 sec = find_section (filedata, ".dynamic");
7278 if (sec == NULL || sec->sh_size == 0)
7280 /* A corresponding .dynamic section is expected, but on
7281 IA-64/OpenVMS it is OK for it to be missing. */
7282 if (!is_ia64_vms (filedata))
7283 error (_("no .dynamic section in the dynamic segment\n"));
7284 break;
7287 if (sec->sh_type == SHT_NOBITS)
7289 dynamic_addr = 0;
7290 dynamic_size = 0;
7291 break;
7294 dynamic_addr = sec->sh_offset;
7295 dynamic_size = sec->sh_size;
7297 /* The PT_DYNAMIC segment, which is used by the run-time
7298 loader, should exactly match the .dynamic section. */
7299 if (do_checks
7300 && (dynamic_addr != segment->p_offset
7301 || dynamic_size != segment->p_filesz))
7302 warn (_("\
7303 the .dynamic section is not the same as the dynamic segment\n"));
7306 /* PR binutils/17512: Avoid corrupt dynamic section info in the
7307 segment. Check this after matching against the section headers
7308 so we don't warn on debuginfo file (which have NOBITS .dynamic
7309 sections). */
7310 if (dynamic_addr > filedata->file_size
7311 || (dynamic_size > filedata->file_size - dynamic_addr))
7313 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
7314 dynamic_addr = 0;
7315 dynamic_size = 0;
7317 break;
7319 case PT_INTERP:
7320 if (segment->p_offset >= filedata->file_size
7321 || segment->p_filesz > filedata->file_size - segment->p_offset
7322 || segment->p_filesz - 1 >= (size_t) -2
7323 || fseek64 (filedata->handle,
7324 filedata->archive_file_offset + segment->p_offset,
7325 SEEK_SET))
7326 error (_("Unable to find program interpreter name\n"));
7327 else
7329 size_t len = segment->p_filesz;
7330 free (filedata->program_interpreter);
7331 filedata->program_interpreter = xmalloc (len + 1);
7332 len = fread (filedata->program_interpreter, 1, len,
7333 filedata->handle);
7334 filedata->program_interpreter[len] = 0;
7336 if (do_segments)
7337 printf (_(" [Requesting program interpreter: %s]\n"),
7338 printable_string (filedata->program_interpreter, 0));
7340 break;
7344 if (do_segments
7345 && filedata->section_headers != NULL
7346 && filedata->string_table != NULL)
7348 printf (_("\n Section to Segment mapping:\n"));
7349 printf (_(" Segment Sections...\n"));
7351 for (i = 0; i < filedata->file_header.e_phnum; i++)
7353 unsigned int j;
7354 Elf_Internal_Shdr * section;
7356 segment = filedata->program_headers + i;
7357 section = filedata->section_headers + 1;
7359 printf (" %2.2d ", i);
7361 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
7363 if (!ELF_TBSS_SPECIAL (section, segment)
7364 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
7365 printf ("%s ", printable_section_name (filedata, section));
7368 putc ('\n',stdout);
7372 filedata->dynamic_addr = dynamic_addr;
7373 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
7374 return;
7376 no_headers:
7377 filedata->dynamic_addr = 0;
7378 filedata->dynamic_size = 1;
7382 /* Find the file offset corresponding to VMA by using the program headers. */
7384 static int64_t
7385 offset_from_vma (Filedata * filedata, uint64_t vma, uint64_t size)
7387 Elf_Internal_Phdr * seg;
7389 if (! get_program_headers (filedata))
7391 warn (_("Cannot interpret virtual addresses without program headers.\n"));
7392 return (long) vma;
7395 for (seg = filedata->program_headers;
7396 seg < filedata->program_headers + filedata->file_header.e_phnum;
7397 ++seg)
7399 if (seg->p_type != PT_LOAD)
7400 continue;
7402 if (vma >= (seg->p_vaddr & -seg->p_align)
7403 && vma + size <= seg->p_vaddr + seg->p_filesz)
7404 return vma - seg->p_vaddr + seg->p_offset;
7407 warn (_("Virtual address %#" PRIx64
7408 " not located in any PT_LOAD segment.\n"), vma);
7409 return vma;
7413 /* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
7414 If PROBE is true, this is just a probe and we do not generate any error
7415 messages if the load fails. */
7417 static bool
7418 get_32bit_section_headers (Filedata * filedata, bool probe)
7420 Elf32_External_Shdr * shdrs;
7421 Elf_Internal_Shdr * internal;
7422 unsigned int i;
7423 unsigned int size = filedata->file_header.e_shentsize;
7424 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
7426 /* PR binutils/17531: Cope with unexpected section header sizes. */
7427 if (size == 0 || num == 0)
7428 return false;
7430 /* The section header cannot be at the start of the file - that is
7431 where the ELF file header is located. A file with absolutely no
7432 sections in it will use a shoff of 0. */
7433 if (filedata->file_header.e_shoff == 0)
7434 return false;
7436 if (size < sizeof * shdrs)
7438 if (! probe)
7439 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
7440 return false;
7442 if (!probe && size > sizeof * shdrs)
7443 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
7445 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
7446 size, num,
7447 probe ? NULL : _("section headers"));
7448 if (shdrs == NULL)
7449 return false;
7451 filedata->section_headers = (Elf_Internal_Shdr *)
7452 cmalloc (num, sizeof (Elf_Internal_Shdr));
7453 if (filedata->section_headers == NULL)
7455 if (!probe)
7456 error (_("Out of memory reading %u section headers\n"), num);
7457 free (shdrs);
7458 return false;
7461 for (i = 0, internal = filedata->section_headers;
7462 i < num;
7463 i++, internal++)
7465 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
7466 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
7467 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
7468 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
7469 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
7470 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
7471 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
7472 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
7473 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
7474 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
7475 if (!probe && internal->sh_link > num)
7476 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
7477 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
7478 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
7481 free (shdrs);
7482 return true;
7485 /* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
7487 static bool
7488 get_64bit_section_headers (Filedata * filedata, bool probe)
7490 Elf64_External_Shdr * shdrs;
7491 Elf_Internal_Shdr * internal;
7492 unsigned int i;
7493 unsigned int size = filedata->file_header.e_shentsize;
7494 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
7496 /* PR binutils/17531: Cope with unexpected section header sizes. */
7497 if (size == 0 || num == 0)
7498 return false;
7500 /* The section header cannot be at the start of the file - that is
7501 where the ELF file header is located. A file with absolutely no
7502 sections in it will use a shoff of 0. */
7503 if (filedata->file_header.e_shoff == 0)
7504 return false;
7506 if (size < sizeof * shdrs)
7508 if (! probe)
7509 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
7510 return false;
7513 if (! probe && size > sizeof * shdrs)
7514 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
7516 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
7517 filedata->file_header.e_shoff,
7518 size, num,
7519 probe ? NULL : _("section headers"));
7520 if (shdrs == NULL)
7521 return false;
7523 filedata->section_headers = (Elf_Internal_Shdr *)
7524 cmalloc (num, sizeof (Elf_Internal_Shdr));
7525 if (filedata->section_headers == NULL)
7527 if (! probe)
7528 error (_("Out of memory reading %u section headers\n"), num);
7529 free (shdrs);
7530 return false;
7533 for (i = 0, internal = filedata->section_headers;
7534 i < num;
7535 i++, internal++)
7537 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
7538 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
7539 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
7540 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
7541 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
7542 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
7543 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
7544 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
7545 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
7546 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
7547 if (!probe && internal->sh_link > num)
7548 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
7549 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
7550 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
7553 free (shdrs);
7554 return true;
7557 static bool
7558 get_section_headers (Filedata *filedata, bool probe)
7560 if (filedata->section_headers != NULL)
7561 return true;
7563 if (is_32bit_elf)
7564 return get_32bit_section_headers (filedata, probe);
7565 else
7566 return get_64bit_section_headers (filedata, probe);
7569 static Elf_Internal_Sym *
7570 get_32bit_elf_symbols (Filedata *filedata,
7571 Elf_Internal_Shdr *section,
7572 uint64_t *num_syms_return)
7574 uint64_t number = 0;
7575 Elf32_External_Sym * esyms = NULL;
7576 Elf_External_Sym_Shndx * shndx = NULL;
7577 Elf_Internal_Sym * isyms = NULL;
7578 Elf_Internal_Sym * psym;
7579 unsigned int j;
7580 elf_section_list * entry;
7582 if (section->sh_size == 0)
7584 if (num_syms_return != NULL)
7585 * num_syms_return = 0;
7586 return NULL;
7589 /* Run some sanity checks first. */
7590 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
7592 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
7593 printable_section_name (filedata, section),
7594 section->sh_entsize);
7595 goto exit_point;
7598 if (section->sh_size > filedata->file_size)
7600 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
7601 printable_section_name (filedata, section),
7602 section->sh_size);
7603 goto exit_point;
7606 number = section->sh_size / section->sh_entsize;
7608 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
7610 error (_("Size (%#" PRIx64 ") of section %s "
7611 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7612 section->sh_size,
7613 printable_section_name (filedata, section),
7614 section->sh_entsize);
7615 goto exit_point;
7618 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
7619 section->sh_size, _("symbols"));
7620 if (esyms == NULL)
7621 goto exit_point;
7623 shndx = NULL;
7624 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
7626 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
7627 continue;
7629 if (shndx != NULL)
7631 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7632 free (shndx);
7635 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7636 entry->hdr->sh_offset,
7637 1, entry->hdr->sh_size,
7638 _("symbol table section indices"));
7639 if (shndx == NULL)
7640 goto exit_point;
7642 /* PR17531: file: heap-buffer-overflow */
7643 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7645 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
7646 printable_section_name (filedata, entry->hdr),
7647 entry->hdr->sh_size,
7648 section->sh_size);
7649 goto exit_point;
7653 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
7655 if (isyms == NULL)
7657 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
7658 goto exit_point;
7661 for (j = 0, psym = isyms; j < number; j++, psym++)
7663 psym->st_name = BYTE_GET (esyms[j].st_name);
7664 psym->st_value = BYTE_GET (esyms[j].st_value);
7665 psym->st_size = BYTE_GET (esyms[j].st_size);
7666 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
7667 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
7668 psym->st_shndx
7669 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
7670 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7671 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
7672 psym->st_info = BYTE_GET (esyms[j].st_info);
7673 psym->st_other = BYTE_GET (esyms[j].st_other);
7676 exit_point:
7677 free (shndx);
7678 free (esyms);
7680 if (num_syms_return != NULL)
7681 * num_syms_return = isyms == NULL ? 0 : number;
7683 return isyms;
7686 static Elf_Internal_Sym *
7687 get_64bit_elf_symbols (Filedata *filedata,
7688 Elf_Internal_Shdr *section,
7689 uint64_t *num_syms_return)
7691 uint64_t number = 0;
7692 Elf64_External_Sym * esyms = NULL;
7693 Elf_External_Sym_Shndx * shndx = NULL;
7694 Elf_Internal_Sym * isyms = NULL;
7695 Elf_Internal_Sym * psym;
7696 unsigned int j;
7697 elf_section_list * entry;
7699 if (section->sh_size == 0)
7701 if (num_syms_return != NULL)
7702 * num_syms_return = 0;
7703 return NULL;
7706 /* Run some sanity checks first. */
7707 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
7709 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
7710 printable_section_name (filedata, section),
7711 section->sh_entsize);
7712 goto exit_point;
7715 if (section->sh_size > filedata->file_size)
7717 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
7718 printable_section_name (filedata, section),
7719 section->sh_size);
7720 goto exit_point;
7723 number = section->sh_size / section->sh_entsize;
7725 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
7727 error (_("Size (%#" PRIx64 ") of section %s "
7728 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7729 section->sh_size,
7730 printable_section_name (filedata, section),
7731 section->sh_entsize);
7732 goto exit_point;
7735 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
7736 section->sh_size, _("symbols"));
7737 if (!esyms)
7738 goto exit_point;
7740 shndx = NULL;
7741 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
7743 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
7744 continue;
7746 if (shndx != NULL)
7748 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7749 free (shndx);
7752 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7753 entry->hdr->sh_offset,
7754 1, entry->hdr->sh_size,
7755 _("symbol table section indices"));
7756 if (shndx == NULL)
7757 goto exit_point;
7759 /* PR17531: file: heap-buffer-overflow */
7760 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7762 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
7763 printable_section_name (filedata, entry->hdr),
7764 entry->hdr->sh_size,
7765 section->sh_size);
7766 goto exit_point;
7770 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
7772 if (isyms == NULL)
7774 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
7775 goto exit_point;
7778 for (j = 0, psym = isyms; j < number; j++, psym++)
7780 psym->st_name = BYTE_GET (esyms[j].st_name);
7781 psym->st_info = BYTE_GET (esyms[j].st_info);
7782 psym->st_other = BYTE_GET (esyms[j].st_other);
7783 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
7785 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
7786 psym->st_shndx
7787 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
7788 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7789 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
7791 psym->st_value = BYTE_GET (esyms[j].st_value);
7792 psym->st_size = BYTE_GET (esyms[j].st_size);
7795 exit_point:
7796 free (shndx);
7797 free (esyms);
7799 if (num_syms_return != NULL)
7800 * num_syms_return = isyms == NULL ? 0 : number;
7802 return isyms;
7805 static Elf_Internal_Sym *
7806 get_elf_symbols (Filedata *filedata,
7807 Elf_Internal_Shdr *section,
7808 uint64_t *num_syms_return)
7810 if (is_32bit_elf)
7811 return get_32bit_elf_symbols (filedata, section, num_syms_return);
7812 else
7813 return get_64bit_elf_symbols (filedata, section, num_syms_return);
7816 static const char *
7817 get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
7819 static char buff[1024];
7820 char * p = buff;
7821 unsigned int field_size = is_32bit_elf ? 8 : 16;
7822 signed int sindex;
7823 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
7824 uint64_t os_flags = 0;
7825 uint64_t proc_flags = 0;
7826 uint64_t unknown_flags = 0;
7827 static const struct
7829 const char * str;
7830 unsigned int len;
7832 flags [] =
7834 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
7835 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
7836 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
7837 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
7838 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
7839 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
7840 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
7841 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
7842 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
7843 /* 9 */ { STRING_COMMA_LEN ("TLS") },
7844 /* IA-64 specific. */
7845 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
7846 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
7847 /* IA-64 OpenVMS specific. */
7848 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
7849 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
7850 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
7851 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
7852 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
7853 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
7854 /* Generic. */
7855 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
7856 /* SPARC specific. */
7857 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
7858 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
7859 /* ARM specific. */
7860 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
7861 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
7862 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
7863 /* GNU specific. */
7864 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
7865 /* VLE specific. */
7866 /* 25 */ { STRING_COMMA_LEN ("VLE") },
7867 /* GNU specific. */
7868 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
7871 if (do_section_details)
7872 p += sprintf (p, "[%*.*lx]: ",
7873 field_size, field_size, (unsigned long) sh_flags);
7875 while (sh_flags)
7877 uint64_t flag;
7879 flag = sh_flags & - sh_flags;
7880 sh_flags &= ~ flag;
7882 if (do_section_details)
7884 switch (flag)
7886 case SHF_WRITE: sindex = 0; break;
7887 case SHF_ALLOC: sindex = 1; break;
7888 case SHF_EXECINSTR: sindex = 2; break;
7889 case SHF_MERGE: sindex = 3; break;
7890 case SHF_STRINGS: sindex = 4; break;
7891 case SHF_INFO_LINK: sindex = 5; break;
7892 case SHF_LINK_ORDER: sindex = 6; break;
7893 case SHF_OS_NONCONFORMING: sindex = 7; break;
7894 case SHF_GROUP: sindex = 8; break;
7895 case SHF_TLS: sindex = 9; break;
7896 case SHF_EXCLUDE: sindex = 18; break;
7897 case SHF_COMPRESSED: sindex = 20; break;
7899 default:
7900 sindex = -1;
7901 switch (filedata->file_header.e_machine)
7903 case EM_IA_64:
7904 if (flag == SHF_IA_64_SHORT)
7905 sindex = 10;
7906 else if (flag == SHF_IA_64_NORECOV)
7907 sindex = 11;
7908 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
7909 switch (flag)
7911 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
7912 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
7913 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
7914 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
7915 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
7916 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
7917 default: break;
7919 break;
7921 case EM_386:
7922 case EM_IAMCU:
7923 case EM_X86_64:
7924 case EM_L1OM:
7925 case EM_K1OM:
7926 case EM_OLD_SPARCV9:
7927 case EM_SPARC32PLUS:
7928 case EM_SPARCV9:
7929 case EM_SPARC:
7930 if (flag == SHF_ORDERED)
7931 sindex = 19;
7932 break;
7934 case EM_ARM:
7935 switch (flag)
7937 case SHF_ENTRYSECT: sindex = 21; break;
7938 case SHF_ARM_PURECODE: sindex = 22; break;
7939 case SHF_COMDEF: sindex = 23; break;
7940 default: break;
7942 break;
7943 case EM_PPC:
7944 if (flag == SHF_PPC_VLE)
7945 sindex = 25;
7946 break;
7947 default:
7948 break;
7951 switch (filedata->file_header.e_ident[EI_OSABI])
7953 case ELFOSABI_GNU:
7954 case ELFOSABI_FREEBSD:
7955 if (flag == SHF_GNU_RETAIN)
7956 sindex = 26;
7957 /* Fall through */
7958 case ELFOSABI_NONE:
7959 if (flag == SHF_GNU_MBIND)
7960 /* We should not recognize SHF_GNU_MBIND for
7961 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7962 not set the EI_OSABI header byte. */
7963 sindex = 24;
7964 break;
7965 default:
7966 break;
7968 break;
7971 if (sindex != -1)
7973 if (p != buff + field_size + 4)
7975 if (size < (10 + 2))
7977 warn (_("Internal error: not enough buffer room for section flag info"));
7978 return _("<unknown>");
7980 size -= 2;
7981 *p++ = ',';
7982 *p++ = ' ';
7985 size -= flags [sindex].len;
7986 p = stpcpy (p, flags [sindex].str);
7988 else if (flag & SHF_MASKOS)
7989 os_flags |= flag;
7990 else if (flag & SHF_MASKPROC)
7991 proc_flags |= flag;
7992 else
7993 unknown_flags |= flag;
7995 else
7997 switch (flag)
7999 case SHF_WRITE: *p = 'W'; break;
8000 case SHF_ALLOC: *p = 'A'; break;
8001 case SHF_EXECINSTR: *p = 'X'; break;
8002 case SHF_MERGE: *p = 'M'; break;
8003 case SHF_STRINGS: *p = 'S'; break;
8004 case SHF_INFO_LINK: *p = 'I'; break;
8005 case SHF_LINK_ORDER: *p = 'L'; break;
8006 case SHF_OS_NONCONFORMING: *p = 'O'; break;
8007 case SHF_GROUP: *p = 'G'; break;
8008 case SHF_TLS: *p = 'T'; break;
8009 case SHF_EXCLUDE: *p = 'E'; break;
8010 case SHF_COMPRESSED: *p = 'C'; break;
8012 default:
8013 if ((filedata->file_header.e_machine == EM_X86_64
8014 || filedata->file_header.e_machine == EM_L1OM
8015 || filedata->file_header.e_machine == EM_K1OM)
8016 && flag == SHF_X86_64_LARGE)
8017 *p = 'l';
8018 else if (filedata->file_header.e_machine == EM_ARM
8019 && flag == SHF_ARM_PURECODE)
8020 *p = 'y';
8021 else if (filedata->file_header.e_machine == EM_PPC
8022 && flag == SHF_PPC_VLE)
8023 *p = 'v';
8024 else if (flag & SHF_MASKOS)
8026 switch (filedata->file_header.e_ident[EI_OSABI])
8028 case ELFOSABI_GNU:
8029 case ELFOSABI_FREEBSD:
8030 if (flag == SHF_GNU_RETAIN)
8032 *p = 'R';
8033 break;
8035 /* Fall through */
8036 case ELFOSABI_NONE:
8037 if (flag == SHF_GNU_MBIND)
8039 /* We should not recognize SHF_GNU_MBIND for
8040 ELFOSABI_NONE, but binutils as of 2019-07-23 did
8041 not set the EI_OSABI header byte. */
8042 *p = 'D';
8043 break;
8045 /* Fall through */
8046 default:
8047 *p = 'o';
8048 sh_flags &= ~SHF_MASKOS;
8049 break;
8052 else if (flag & SHF_MASKPROC)
8054 *p = 'p';
8055 sh_flags &= ~ SHF_MASKPROC;
8057 else
8058 *p = 'x';
8059 break;
8061 p++;
8065 if (do_section_details)
8067 if (os_flags)
8069 if (p != buff + field_size + 4)
8071 if (size < 2 + 5 + field_size + 1)
8073 warn (_("Internal error: not enough buffer room for section flag info"));
8074 return _("<unknown>");
8076 size -= 2;
8077 *p++ = ',';
8078 *p++ = ' ';
8080 size -= 5 + field_size;
8081 p += sprintf (p, "OS (%*.*lx)", field_size, field_size,
8082 (unsigned long) os_flags);
8084 if (proc_flags)
8086 if (p != buff + field_size + 4)
8088 if (size < 2 + 7 + field_size + 1)
8090 warn (_("Internal error: not enough buffer room for section flag info"));
8091 return _("<unknown>");
8093 size -= 2;
8094 *p++ = ',';
8095 *p++ = ' ';
8097 size -= 7 + field_size;
8098 p += sprintf (p, "PROC (%*.*lx)", field_size, field_size,
8099 (unsigned long) proc_flags);
8101 if (unknown_flags)
8103 if (p != buff + field_size + 4)
8105 if (size < 2 + 10 + field_size + 1)
8107 warn (_("Internal error: not enough buffer room for section flag info"));
8108 return _("<unknown>");
8110 size -= 2;
8111 *p++ = ',';
8112 *p++ = ' ';
8114 size -= 10 + field_size;
8115 p += sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8116 (unsigned long) unknown_flags);
8120 *p = '\0';
8121 return buff;
8124 static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
8125 get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf,
8126 uint64_t size)
8128 if (is_32bit_elf)
8130 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
8132 if (size < sizeof (* echdr))
8134 error (_("Compressed section is too small even for a compression header\n"));
8135 return 0;
8138 chdr->ch_type = BYTE_GET (echdr->ch_type);
8139 chdr->ch_size = BYTE_GET (echdr->ch_size);
8140 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
8141 return sizeof (*echdr);
8143 else
8145 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
8147 if (size < sizeof (* echdr))
8149 error (_("Compressed section is too small even for a compression header\n"));
8150 return 0;
8153 chdr->ch_type = BYTE_GET (echdr->ch_type);
8154 chdr->ch_size = BYTE_GET (echdr->ch_size);
8155 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
8156 return sizeof (*echdr);
8160 static bool
8161 process_section_headers (Filedata * filedata)
8163 Elf_Internal_Shdr * section;
8164 unsigned int i;
8166 if (filedata->file_header.e_shnum == 0)
8168 /* PR binutils/12467. */
8169 if (filedata->file_header.e_shoff != 0)
8171 warn (_("possibly corrupt ELF file header - it has a non-zero"
8172 " section header offset, but no section headers\n"));
8173 return false;
8175 else if (do_sections)
8176 printf (_("\nThere are no sections in this file.\n"));
8178 return true;
8181 if (do_sections && !do_header)
8183 if (filedata->is_separate && process_links)
8184 printf (_("In linked file '%s': "),
8185 printable_string (filedata->file_name, 0));
8186 if (! filedata->is_separate || process_links)
8187 printf (ngettext ("There is %d section header, "
8188 "starting at offset %#" PRIx64 ":\n",
8189 "There are %d section headers, "
8190 "starting at offset %#" PRIx64 ":\n",
8191 filedata->file_header.e_shnum),
8192 filedata->file_header.e_shnum,
8193 filedata->file_header.e_shoff);
8196 if (!get_section_headers (filedata, false))
8197 return false;
8199 /* Read in the string table, so that we have names to display. */
8200 if (filedata->string_table == NULL
8201 && filedata->file_header.e_shstrndx != SHN_UNDEF
8202 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
8204 section = filedata->section_headers + filedata->file_header.e_shstrndx;
8206 if (section->sh_size != 0)
8208 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
8209 1, section->sh_size,
8210 _("string table"));
8212 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
8216 /* Scan the sections for the dynamic symbol table
8217 and dynamic string table and debug sections. */
8218 eh_addr_size = is_32bit_elf ? 4 : 8;
8219 switch (filedata->file_header.e_machine)
8221 case EM_MIPS:
8222 case EM_MIPS_RS3_LE:
8223 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
8224 FDE addresses. However, the ABI also has a semi-official ILP32
8225 variant for which the normal FDE address size rules apply.
8227 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
8228 section, where XX is the size of longs in bits. Unfortunately,
8229 earlier compilers provided no way of distinguishing ILP32 objects
8230 from LP64 objects, so if there's any doubt, we should assume that
8231 the official LP64 form is being used. */
8232 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == EF_MIPS_ABI_EABI64
8233 && find_section (filedata, ".gcc_compiled_long32") == NULL)
8234 eh_addr_size = 8;
8235 break;
8237 case EM_H8_300:
8238 case EM_H8_300H:
8239 switch (filedata->file_header.e_flags & EF_H8_MACH)
8241 case E_H8_MACH_H8300:
8242 case E_H8_MACH_H8300HN:
8243 case E_H8_MACH_H8300SN:
8244 case E_H8_MACH_H8300SXN:
8245 eh_addr_size = 2;
8246 break;
8247 case E_H8_MACH_H8300H:
8248 case E_H8_MACH_H8300S:
8249 case E_H8_MACH_H8300SX:
8250 eh_addr_size = 4;
8251 break;
8253 break;
8255 case EM_M32C_OLD:
8256 case EM_M32C:
8257 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
8259 case EF_M32C_CPU_M16C:
8260 eh_addr_size = 2;
8261 break;
8263 break;
8266 #define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
8267 do \
8269 uint64_t expected_entsize = is_32bit_elf ? size32 : size64; \
8270 if (section->sh_entsize != expected_entsize) \
8272 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
8273 i, section->sh_entsize); \
8274 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
8275 expected_entsize); \
8276 section->sh_entsize = expected_entsize; \
8279 while (0)
8281 #define CHECK_ENTSIZE(section, i, type) \
8282 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
8283 sizeof (Elf64_External_##type))
8285 for (i = 0, section = filedata->section_headers;
8286 i < filedata->file_header.e_shnum;
8287 i++, section++)
8289 const char *name = printable_section_name (filedata, section);
8291 /* Run some sanity checks on the headers and
8292 possibly fill in some file data as well. */
8293 switch (section->sh_type)
8295 case SHT_DYNSYM:
8296 if (filedata->dynamic_symbols != NULL)
8298 error (_("File contains multiple dynamic symbol tables\n"));
8299 continue;
8302 CHECK_ENTSIZE (section, i, Sym);
8303 filedata->dynamic_symbols
8304 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8305 filedata->dynamic_symtab_section = section;
8306 break;
8308 case SHT_STRTAB:
8309 if (streq (name, ".dynstr"))
8311 if (filedata->dynamic_strings != NULL)
8313 error (_("File contains multiple dynamic string tables\n"));
8314 continue;
8317 filedata->dynamic_strings
8318 = (char *) get_data (NULL, filedata, section->sh_offset,
8319 1, section->sh_size, _("dynamic strings"));
8320 filedata->dynamic_strings_length
8321 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8322 filedata->dynamic_strtab_section = section;
8324 break;
8326 case SHT_SYMTAB_SHNDX:
8328 elf_section_list * entry = xmalloc (sizeof * entry);
8330 entry->hdr = section;
8331 entry->next = filedata->symtab_shndx_list;
8332 filedata->symtab_shndx_list = entry;
8334 break;
8336 case SHT_SYMTAB:
8337 CHECK_ENTSIZE (section, i, Sym);
8338 break;
8340 case SHT_GROUP:
8341 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
8342 break;
8344 case SHT_REL:
8345 CHECK_ENTSIZE (section, i, Rel);
8346 if (do_checks && section->sh_size == 0)
8347 warn (_("Section '%s': zero-sized relocation section\n"), name);
8348 break;
8350 case SHT_RELA:
8351 CHECK_ENTSIZE (section, i, Rela);
8352 if (do_checks && section->sh_size == 0)
8353 warn (_("Section '%s': zero-sized relocation section\n"), name);
8354 break;
8356 case SHT_RELR:
8357 CHECK_ENTSIZE (section, i, Relr);
8358 break;
8360 case SHT_NOTE:
8361 case SHT_PROGBITS:
8362 /* Having a zero sized section is not illegal according to the
8363 ELF standard, but it might be an indication that something
8364 is wrong. So issue a warning if we are running in lint mode. */
8365 if (do_checks && section->sh_size == 0)
8366 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
8367 break;
8369 default:
8370 break;
8373 if ((do_debugging || do_debug_info || do_debug_abbrevs
8374 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
8375 || do_debug_aranges || do_debug_frames || do_debug_macinfo
8376 || do_debug_str || do_debug_str_offsets || do_debug_loc
8377 || do_debug_ranges
8378 || do_debug_addr || do_debug_cu_index || do_debug_links)
8379 && (startswith (name, ".debug_")
8380 || startswith (name, ".zdebug_")))
8382 if (name[1] == 'z')
8383 name += sizeof (".zdebug_") - 1;
8384 else
8385 name += sizeof (".debug_") - 1;
8387 if (do_debugging
8388 || (do_debug_info && startswith (name, "info"))
8389 || (do_debug_info && startswith (name, "types"))
8390 || (do_debug_abbrevs && startswith (name, "abbrev"))
8391 || (do_debug_lines && strcmp (name, "line") == 0)
8392 || (do_debug_lines && startswith (name, "line."))
8393 || (do_debug_pubnames && startswith (name, "pubnames"))
8394 || (do_debug_pubtypes && startswith (name, "pubtypes"))
8395 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
8396 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
8397 || (do_debug_aranges && startswith (name, "aranges"))
8398 || (do_debug_ranges && startswith (name, "ranges"))
8399 || (do_debug_ranges && startswith (name, "rnglists"))
8400 || (do_debug_frames && startswith (name, "frame"))
8401 || (do_debug_macinfo && startswith (name, "macinfo"))
8402 || (do_debug_macinfo && startswith (name, "macro"))
8403 || (do_debug_str && startswith (name, "str"))
8404 || (do_debug_links && startswith (name, "sup"))
8405 || (do_debug_str_offsets && startswith (name, "str_offsets"))
8406 || (do_debug_loc && startswith (name, "loc"))
8407 || (do_debug_loc && startswith (name, "loclists"))
8408 || (do_debug_addr && startswith (name, "addr"))
8409 || (do_debug_cu_index && startswith (name, "cu_index"))
8410 || (do_debug_cu_index && startswith (name, "tu_index"))
8412 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
8414 /* Linkonce section to be combined with .debug_info at link time. */
8415 else if ((do_debugging || do_debug_info)
8416 && startswith (name, ".gnu.linkonce.wi."))
8417 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
8418 else if (do_debug_frames && streq (name, ".eh_frame"))
8419 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
8420 else if (do_debug_frames && streq (name, ".eh_frame_hdr"))
8421 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
8422 else if (do_gdb_index && (streq (name, ".gdb_index")
8423 || streq (name, ".debug_names")))
8424 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
8425 /* Trace sections for Itanium VMS. */
8426 else if ((do_debugging || do_trace_info || do_trace_abbrevs
8427 || do_trace_aranges)
8428 && startswith (name, ".trace_"))
8430 name += sizeof (".trace_") - 1;
8432 if (do_debugging
8433 || (do_trace_info && streq (name, "info"))
8434 || (do_trace_abbrevs && streq (name, "abbrev"))
8435 || (do_trace_aranges && streq (name, "aranges"))
8437 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
8439 else if ((do_debugging || do_debug_links)
8440 && (startswith (name, ".gnu_debuglink")
8441 || startswith (name, ".gnu_debugaltlink")))
8442 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
8445 if (! do_sections)
8446 return true;
8448 if (filedata->is_separate && ! process_links)
8449 return true;
8451 if (filedata->is_separate)
8452 printf (_("\nSection Headers in linked file '%s':\n"),
8453 printable_string (filedata->file_name, 0));
8454 else if (filedata->file_header.e_shnum > 1)
8455 printf (_("\nSection Headers:\n"));
8456 else
8457 printf (_("\nSection Header:\n"));
8459 if (is_32bit_elf)
8461 if (do_section_details)
8463 printf (_(" [Nr] Name\n"));
8464 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
8466 else
8467 printf
8468 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
8470 else if (do_wide)
8472 if (do_section_details)
8474 printf (_(" [Nr] Name\n"));
8475 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
8477 else
8478 printf
8479 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
8481 else
8483 if (do_section_details)
8485 printf (_(" [Nr] Name\n"));
8486 printf (_(" Type Address Offset Link\n"));
8487 printf (_(" Size EntSize Info Align\n"));
8489 else
8491 printf (_(" [Nr] Name Type Address Offset\n"));
8492 printf (_(" Size EntSize Flags Link Info Align\n"));
8496 if (do_section_details)
8497 printf (_(" Flags\n"));
8499 for (i = 0, section = filedata->section_headers;
8500 i < filedata->file_header.e_shnum;
8501 i++, section++)
8503 /* Run some sanity checks on the section header. */
8505 /* Check the sh_link field. */
8506 switch (section->sh_type)
8508 case SHT_REL:
8509 case SHT_RELR:
8510 case SHT_RELA:
8511 if (section->sh_link == 0
8512 && (filedata->file_header.e_type == ET_EXEC
8513 || filedata->file_header.e_type == ET_DYN))
8514 /* A dynamic relocation section where all entries use a
8515 zero symbol index need not specify a symtab section. */
8516 break;
8517 /* Fall through. */
8518 case SHT_SYMTAB_SHNDX:
8519 case SHT_GROUP:
8520 case SHT_HASH:
8521 case SHT_GNU_HASH:
8522 case SHT_GNU_versym:
8523 if (section->sh_link == 0
8524 || section->sh_link >= filedata->file_header.e_shnum
8525 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
8526 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
8527 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
8528 i, section->sh_link);
8529 break;
8531 case SHT_DYNAMIC:
8532 case SHT_SYMTAB:
8533 case SHT_DYNSYM:
8534 case SHT_GNU_verneed:
8535 case SHT_GNU_verdef:
8536 case SHT_GNU_LIBLIST:
8537 if (section->sh_link == 0
8538 || section->sh_link >= filedata->file_header.e_shnum
8539 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
8540 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
8541 i, section->sh_link);
8542 break;
8544 case SHT_INIT_ARRAY:
8545 case SHT_FINI_ARRAY:
8546 case SHT_PREINIT_ARRAY:
8547 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
8548 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
8549 i, section->sh_link);
8550 break;
8552 default:
8553 /* FIXME: Add support for target specific section types. */
8554 #if 0 /* Currently we do not check other section types as there are too
8555 many special cases. Stab sections for example have a type
8556 of SHT_PROGBITS but an sh_link field that links to the .stabstr
8557 section. */
8558 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
8559 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
8560 i, section->sh_link);
8561 #endif
8562 break;
8565 /* Check the sh_info field. */
8566 switch (section->sh_type)
8568 case SHT_REL:
8569 case SHT_RELA:
8570 if (section->sh_info == 0
8571 && (filedata->file_header.e_type == ET_EXEC
8572 || filedata->file_header.e_type == ET_DYN))
8573 /* Dynamic relocations apply to segments, so they do not
8574 need to specify the section they relocate. */
8575 break;
8576 if (section->sh_info == 0
8577 || section->sh_info >= filedata->file_header.e_shnum
8578 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
8579 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
8580 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
8581 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
8582 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
8583 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
8584 /* FIXME: Are other section types valid ? */
8585 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
8586 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
8587 i, section->sh_info);
8588 break;
8590 case SHT_DYNAMIC:
8591 case SHT_HASH:
8592 case SHT_SYMTAB_SHNDX:
8593 case SHT_INIT_ARRAY:
8594 case SHT_FINI_ARRAY:
8595 case SHT_PREINIT_ARRAY:
8596 if (section->sh_info != 0)
8597 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
8598 i, section->sh_info);
8599 break;
8601 case SHT_GROUP:
8602 case SHT_SYMTAB:
8603 case SHT_DYNSYM:
8604 /* A symbol index - we assume that it is valid. */
8605 break;
8607 default:
8608 /* FIXME: Add support for target specific section types. */
8609 if (section->sh_type == SHT_NOBITS)
8610 /* NOBITS section headers with non-zero sh_info fields can be
8611 created when a binary is stripped of everything but its debug
8612 information. The stripped sections have their headers
8613 preserved but their types set to SHT_NOBITS. So do not check
8614 this type of section. */
8616 else if (section->sh_flags & SHF_INFO_LINK)
8618 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
8619 warn (_("[%2u]: Expected link to another section in info field"), i);
8621 else if (section->sh_type < SHT_LOOS
8622 && (section->sh_flags & SHF_GNU_MBIND) == 0
8623 && section->sh_info != 0)
8624 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
8625 i, section->sh_info);
8626 break;
8629 /* Check the sh_size field. */
8630 if (section->sh_size > filedata->file_size
8631 && section->sh_type != SHT_NOBITS
8632 && section->sh_type != SHT_NULL
8633 && section->sh_type < SHT_LOOS)
8634 warn (_("Size of section %u is larger than the entire file!\n"), i);
8636 printf (" [%2u] ", i);
8637 if (do_section_details)
8638 printf ("%s\n ", printable_section_name (filedata, section));
8639 else
8640 print_symbol_name (-17, printable_section_name (filedata, section));
8642 printf (do_wide ? " %-15s " : " %-15.15s ",
8643 get_section_type_name (filedata, section->sh_type));
8645 if (is_32bit_elf)
8647 const char * link_too_big = NULL;
8649 print_vma (section->sh_addr, LONG_HEX);
8651 printf ( " %6.6lx %6.6lx %2.2lx",
8652 (unsigned long) section->sh_offset,
8653 (unsigned long) section->sh_size,
8654 (unsigned long) section->sh_entsize);
8656 if (do_section_details)
8657 fputs (" ", stdout);
8658 else
8659 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
8661 if (section->sh_link >= filedata->file_header.e_shnum)
8663 link_too_big = "";
8664 /* The sh_link value is out of range. Normally this indicates
8665 an error but it can have special values in Solaris binaries. */
8666 switch (filedata->file_header.e_machine)
8668 case EM_386:
8669 case EM_IAMCU:
8670 case EM_X86_64:
8671 case EM_L1OM:
8672 case EM_K1OM:
8673 case EM_OLD_SPARCV9:
8674 case EM_SPARC32PLUS:
8675 case EM_SPARCV9:
8676 case EM_SPARC:
8677 if (section->sh_link == (SHN_BEFORE & 0xffff))
8678 link_too_big = "BEFORE";
8679 else if (section->sh_link == (SHN_AFTER & 0xffff))
8680 link_too_big = "AFTER";
8681 break;
8682 default:
8683 break;
8687 if (do_section_details)
8689 if (link_too_big != NULL && * link_too_big)
8690 printf ("<%s> ", link_too_big);
8691 else
8692 printf ("%2u ", section->sh_link);
8693 printf ("%3u %2lu\n", section->sh_info,
8694 (unsigned long) section->sh_addralign);
8696 else
8697 printf ("%2u %3u %2lu\n",
8698 section->sh_link,
8699 section->sh_info,
8700 (unsigned long) section->sh_addralign);
8702 if (link_too_big && ! * link_too_big)
8703 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
8704 i, section->sh_link);
8706 else if (do_wide)
8708 print_vma (section->sh_addr, LONG_HEX);
8710 if ((long) section->sh_offset == section->sh_offset)
8711 printf (" %6.6lx", (unsigned long) section->sh_offset);
8712 else
8714 putchar (' ');
8715 print_vma (section->sh_offset, LONG_HEX);
8718 if ((unsigned long) section->sh_size == section->sh_size)
8719 printf (" %6.6lx", (unsigned long) section->sh_size);
8720 else
8722 putchar (' ');
8723 print_vma (section->sh_size, LONG_HEX);
8726 if ((unsigned long) section->sh_entsize == section->sh_entsize)
8727 printf (" %2.2lx", (unsigned long) section->sh_entsize);
8728 else
8730 putchar (' ');
8731 print_vma (section->sh_entsize, LONG_HEX);
8734 if (do_section_details)
8735 fputs (" ", stdout);
8736 else
8737 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
8739 printf ("%2u %3u ", section->sh_link, section->sh_info);
8741 if ((unsigned long) section->sh_addralign == section->sh_addralign)
8742 printf ("%2lu\n", (unsigned long) section->sh_addralign);
8743 else
8745 print_vma (section->sh_addralign, DEC);
8746 putchar ('\n');
8749 else if (do_section_details)
8751 putchar (' ');
8752 print_vma (section->sh_addr, LONG_HEX);
8753 if ((long) section->sh_offset == section->sh_offset)
8754 printf (" %16.16lx", (unsigned long) section->sh_offset);
8755 else
8757 printf (" ");
8758 print_vma (section->sh_offset, LONG_HEX);
8760 printf (" %u\n ", section->sh_link);
8761 print_vma (section->sh_size, LONG_HEX);
8762 putchar (' ');
8763 print_vma (section->sh_entsize, LONG_HEX);
8765 printf (" %-16u %lu\n",
8766 section->sh_info,
8767 (unsigned long) section->sh_addralign);
8769 else
8771 putchar (' ');
8772 print_vma (section->sh_addr, LONG_HEX);
8773 if ((long) section->sh_offset == section->sh_offset)
8774 printf (" %8.8lx", (unsigned long) section->sh_offset);
8775 else
8777 printf (" ");
8778 print_vma (section->sh_offset, LONG_HEX);
8780 printf ("\n ");
8781 print_vma (section->sh_size, LONG_HEX);
8782 printf (" ");
8783 print_vma (section->sh_entsize, LONG_HEX);
8785 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
8787 printf (" %2u %3u %lu\n",
8788 section->sh_link,
8789 section->sh_info,
8790 (unsigned long) section->sh_addralign);
8793 if (do_section_details)
8795 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
8796 if ((section->sh_flags & SHF_COMPRESSED) != 0)
8798 /* Minimum section size is 12 bytes for 32-bit compression
8799 header + 12 bytes for compressed data header. */
8800 unsigned char buf[24];
8802 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
8803 if (get_data (&buf, filedata, section->sh_offset, 1,
8804 sizeof (buf), _("compression header")))
8806 Elf_Internal_Chdr chdr;
8808 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
8809 printf (_(" [<corrupt>]\n"));
8810 else
8812 if (chdr.ch_type == ch_compress_zlib)
8813 printf (" ZLIB, ");
8814 else if (chdr.ch_type == ch_compress_zstd)
8815 printf (" ZSTD, ");
8816 else
8817 printf (_(" [<unknown>: 0x%x], "),
8818 chdr.ch_type);
8819 print_vma (chdr.ch_size, LONG_HEX);
8820 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
8827 if (!do_section_details)
8829 /* The ordering of the letters shown here matches the ordering of the
8830 corresponding SHF_xxx values, and hence the order in which these
8831 letters will be displayed to the user. */
8832 printf (_("Key to Flags:\n\
8833 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
8834 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
8835 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
8836 switch (filedata->file_header.e_ident[EI_OSABI])
8838 case ELFOSABI_GNU:
8839 case ELFOSABI_FREEBSD:
8840 printf (_("R (retain), "));
8841 /* Fall through */
8842 case ELFOSABI_NONE:
8843 printf (_("D (mbind), "));
8844 break;
8845 default:
8846 break;
8848 if (filedata->file_header.e_machine == EM_X86_64
8849 || filedata->file_header.e_machine == EM_L1OM
8850 || filedata->file_header.e_machine == EM_K1OM)
8851 printf (_("l (large), "));
8852 else if (filedata->file_header.e_machine == EM_ARM)
8853 printf (_("y (purecode), "));
8854 else if (filedata->file_header.e_machine == EM_PPC)
8855 printf (_("v (VLE), "));
8856 printf ("p (processor specific)\n");
8859 return true;
8862 static bool
8863 get_symtab (Filedata * filedata,
8864 Elf_Internal_Shdr * symsec,
8865 Elf_Internal_Sym ** symtab,
8866 uint64_t * nsyms,
8867 char ** strtab,
8868 uint64_t * strtablen)
8870 *strtab = NULL;
8871 *strtablen = 0;
8872 *symtab = get_elf_symbols (filedata, symsec, nsyms);
8874 if (*symtab == NULL)
8875 return false;
8877 if (symsec->sh_link != 0)
8879 Elf_Internal_Shdr *strsec;
8881 if (symsec->sh_link >= filedata->file_header.e_shnum)
8883 error (_("Bad sh_link in symbol table section\n"));
8884 free (*symtab);
8885 *symtab = NULL;
8886 *nsyms = 0;
8887 return false;
8890 strsec = filedata->section_headers + symsec->sh_link;
8892 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
8893 1, strsec->sh_size, _("string table"));
8894 if (*strtab == NULL)
8896 free (*symtab);
8897 *symtab = NULL;
8898 *nsyms = 0;
8899 return false;
8901 *strtablen = strsec->sh_size;
8903 return true;
8906 static const char *
8907 get_group_flags (unsigned int flags)
8909 static char buff[128];
8911 if (flags == 0)
8912 return "";
8913 else if (flags == GRP_COMDAT)
8914 return "COMDAT ";
8916 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
8917 flags,
8918 flags & GRP_MASKOS ? _("<OS specific>") : "",
8919 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
8920 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
8921 ? _("<unknown>") : ""));
8923 return buff;
8926 static bool
8927 process_section_groups (Filedata * filedata)
8929 Elf_Internal_Shdr * section;
8930 unsigned int i;
8931 struct group * group;
8932 Elf_Internal_Shdr * symtab_sec;
8933 Elf_Internal_Shdr * strtab_sec;
8934 Elf_Internal_Sym * symtab;
8935 uint64_t num_syms;
8936 char * strtab;
8937 size_t strtab_size;
8939 /* Don't process section groups unless needed. */
8940 if (!do_unwind && !do_section_groups)
8941 return true;
8943 if (filedata->file_header.e_shnum == 0)
8945 if (do_section_groups)
8947 if (filedata->is_separate)
8948 printf (_("\nThere are no sections group in linked file '%s'.\n"),
8949 printable_string (filedata->file_name, 0));
8950 else
8951 printf (_("\nThere are no section groups in this file.\n"));
8953 return true;
8956 if (filedata->section_headers == NULL)
8958 error (_("Section headers are not available!\n"));
8959 /* PR 13622: This can happen with a corrupt ELF header. */
8960 return false;
8963 filedata->section_headers_groups
8964 = (struct group **) calloc (filedata->file_header.e_shnum,
8965 sizeof (struct group *));
8967 if (filedata->section_headers_groups == NULL)
8969 error (_("Out of memory reading %u section group headers\n"),
8970 filedata->file_header.e_shnum);
8971 return false;
8974 /* Scan the sections for the group section. */
8975 filedata->group_count = 0;
8976 for (i = 0, section = filedata->section_headers;
8977 i < filedata->file_header.e_shnum;
8978 i++, section++)
8979 if (section->sh_type == SHT_GROUP)
8980 filedata->group_count++;
8982 if (filedata->group_count == 0)
8984 if (do_section_groups)
8986 if (filedata->is_separate)
8987 printf (_("\nThere are no section groups in linked file '%s'.\n"),
8988 printable_string (filedata->file_name, 0));
8989 else
8990 printf (_("\nThere are no section groups in this file.\n"));
8993 return true;
8996 filedata->section_groups = (struct group *) calloc (filedata->group_count,
8997 sizeof (struct group));
8999 if (filedata->section_groups == NULL)
9001 error (_("Out of memory reading %zu groups\n"), filedata->group_count);
9002 return false;
9005 symtab_sec = NULL;
9006 strtab_sec = NULL;
9007 symtab = NULL;
9008 num_syms = 0;
9009 strtab = NULL;
9010 strtab_size = 0;
9012 if (filedata->is_separate)
9013 printf (_("Section groups in linked file '%s'\n"),
9014 printable_string (filedata->file_name, 0));
9016 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
9017 i < filedata->file_header.e_shnum;
9018 i++, section++)
9020 if (section->sh_type == SHT_GROUP)
9022 const char * name = printable_section_name (filedata, section);
9023 const char * group_name;
9024 unsigned char * start;
9025 unsigned char * indices;
9026 unsigned int entry, j, size;
9027 Elf_Internal_Shdr * sec;
9028 Elf_Internal_Sym * sym;
9030 /* Get the symbol table. */
9031 if (section->sh_link >= filedata->file_header.e_shnum
9032 || ((sec = filedata->section_headers + section->sh_link)->sh_type
9033 != SHT_SYMTAB))
9035 error (_("Bad sh_link in group section `%s'\n"), name);
9036 continue;
9039 if (symtab_sec != sec)
9041 symtab_sec = sec;
9042 free (symtab);
9043 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
9046 if (symtab == NULL)
9048 error (_("Corrupt header in group section `%s'\n"), name);
9049 continue;
9052 if (section->sh_info >= num_syms)
9054 error (_("Bad sh_info in group section `%s'\n"), name);
9055 continue;
9058 sym = symtab + section->sh_info;
9060 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
9062 if (sym->st_shndx == 0
9063 || sym->st_shndx >= filedata->file_header.e_shnum)
9065 error (_("Bad sh_info in group section `%s'\n"), name);
9066 continue;
9069 group_name = printable_section_name (filedata,
9070 filedata->section_headers
9071 + sym->st_shndx);
9072 strtab_sec = NULL;
9073 free (strtab);
9074 strtab = NULL;
9075 strtab_size = 0;
9077 else
9079 /* Get the string table. */
9080 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
9082 strtab_sec = NULL;
9083 free (strtab);
9084 strtab = NULL;
9085 strtab_size = 0;
9087 else if (strtab_sec
9088 != (sec = filedata->section_headers + symtab_sec->sh_link))
9090 strtab_sec = sec;
9091 free (strtab);
9093 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
9094 1, strtab_sec->sh_size,
9095 _("string table"));
9096 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
9098 group_name = sym->st_name < strtab_size
9099 ? strtab + sym->st_name : _("<corrupt>");
9102 /* PR 17531: file: loop. */
9103 if (section->sh_entsize > section->sh_size)
9105 error (_("Section %s has sh_entsize (%#" PRIx64 ")"
9106 " which is larger than its size (%#" PRIx64 ")\n"),
9107 printable_section_name (filedata, section),
9108 section->sh_entsize,
9109 section->sh_size);
9110 continue;
9113 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
9114 1, section->sh_size,
9115 _("section data"));
9116 if (start == NULL)
9117 continue;
9119 indices = start;
9120 size = (section->sh_size / section->sh_entsize) - 1;
9121 entry = byte_get (indices, 4);
9122 indices += 4;
9124 if (do_section_groups)
9126 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
9127 get_group_flags (entry), i, name, group_name, size);
9129 printf (_(" [Index] Name\n"));
9132 group->group_index = i;
9134 for (j = 0; j < size; j++)
9136 struct group_list * g;
9138 entry = byte_get (indices, 4);
9139 indices += 4;
9141 if (entry >= filedata->file_header.e_shnum)
9143 static unsigned num_group_errors = 0;
9145 if (num_group_errors ++ < 10)
9147 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
9148 entry, i, filedata->file_header.e_shnum - 1);
9149 if (num_group_errors == 10)
9150 warn (_("Further error messages about overlarge group section indices suppressed\n"));
9152 continue;
9155 if (filedata->section_headers_groups [entry] != NULL)
9157 if (entry)
9159 static unsigned num_errs = 0;
9161 if (num_errs ++ < 10)
9163 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
9164 entry, i,
9165 filedata->section_headers_groups [entry]->group_index);
9166 if (num_errs == 10)
9167 warn (_("Further error messages about already contained group sections suppressed\n"));
9169 continue;
9171 else
9173 /* Intel C/C++ compiler may put section 0 in a
9174 section group. We just warn it the first time
9175 and ignore it afterwards. */
9176 static bool warned = false;
9177 if (!warned)
9179 error (_("section 0 in group section [%5u]\n"),
9180 filedata->section_headers_groups [entry]->group_index);
9181 warned = true;
9186 filedata->section_headers_groups [entry] = group;
9188 if (do_section_groups)
9190 sec = filedata->section_headers + entry;
9191 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
9194 g = (struct group_list *) xmalloc (sizeof (struct group_list));
9195 g->section_index = entry;
9196 g->next = group->root;
9197 group->root = g;
9200 free (start);
9202 group++;
9206 free (symtab);
9207 free (strtab);
9208 return true;
9211 /* Data used to display dynamic fixups. */
9213 struct ia64_vms_dynfixup
9215 uint64_t needed_ident; /* Library ident number. */
9216 uint64_t needed; /* Index in the dstrtab of the library name. */
9217 uint64_t fixup_needed; /* Index of the library. */
9218 uint64_t fixup_rela_cnt; /* Number of fixups. */
9219 uint64_t fixup_rela_off; /* Fixups offset in the dynamic segment. */
9222 /* Data used to display dynamic relocations. */
9224 struct ia64_vms_dynimgrela
9226 uint64_t img_rela_cnt; /* Number of relocations. */
9227 uint64_t img_rela_off; /* Reloc offset in the dynamic segment. */
9230 /* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
9231 library). */
9233 static bool
9234 dump_ia64_vms_dynamic_fixups (Filedata * filedata,
9235 struct ia64_vms_dynfixup * fixup,
9236 const char * strtab,
9237 unsigned int strtab_sz)
9239 Elf64_External_VMS_IMAGE_FIXUP * imfs;
9240 size_t i;
9241 const char * lib_name;
9243 imfs = get_data (NULL, filedata,
9244 filedata->dynamic_addr + fixup->fixup_rela_off,
9245 sizeof (*imfs), fixup->fixup_rela_cnt,
9246 _("dynamic section image fixups"));
9247 if (!imfs)
9248 return false;
9250 if (fixup->needed < strtab_sz)
9251 lib_name = strtab + fixup->needed;
9252 else
9254 warn (_("corrupt library name index of %#" PRIx64
9255 " found in dynamic entry"), fixup->needed);
9256 lib_name = "???";
9259 printf (_("\nImage fixups for needed library #%" PRId64
9260 ": %s - ident: %" PRIx64 "\n"),
9261 fixup->fixup_needed, lib_name, fixup->needed_ident);
9262 printf
9263 (_("Seg Offset Type SymVec DataType\n"));
9265 for (i = 0; i < (size_t) fixup->fixup_rela_cnt; i++)
9267 unsigned int type;
9268 const char *rtype;
9270 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
9271 printf ("%016" PRIx64 " ", BYTE_GET (imfs [i].fixup_offset));
9272 type = BYTE_GET (imfs [i].type);
9273 rtype = elf_ia64_reloc_type (type);
9274 if (rtype == NULL)
9275 printf ("0x%08x ", type);
9276 else
9277 printf ("%-32s ", rtype);
9278 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
9279 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
9282 free (imfs);
9283 return true;
9286 /* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
9288 static bool
9289 dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
9291 Elf64_External_VMS_IMAGE_RELA *imrs;
9292 size_t i;
9294 imrs = get_data (NULL, filedata,
9295 filedata->dynamic_addr + imgrela->img_rela_off,
9296 sizeof (*imrs), imgrela->img_rela_cnt,
9297 _("dynamic section image relocations"));
9298 if (!imrs)
9299 return false;
9301 printf (_("\nImage relocs\n"));
9302 printf
9303 (_("Seg Offset Type Addend Seg Sym Off\n"));
9305 for (i = 0; i < (size_t) imgrela->img_rela_cnt; i++)
9307 unsigned int type;
9308 const char *rtype;
9310 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
9311 printf ("%08" PRIx64 " ", BYTE_GET (imrs [i].rela_offset));
9312 type = BYTE_GET (imrs [i].type);
9313 rtype = elf_ia64_reloc_type (type);
9314 if (rtype == NULL)
9315 printf ("0x%08x ", type);
9316 else
9317 printf ("%-31s ", rtype);
9318 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
9319 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
9320 printf ("%08" PRIx64 "\n", BYTE_GET (imrs [i].sym_offset));
9323 free (imrs);
9324 return true;
9327 /* Display IA-64 OpenVMS dynamic relocations and fixups. */
9329 static bool
9330 process_ia64_vms_dynamic_relocs (Filedata * filedata)
9332 struct ia64_vms_dynfixup fixup;
9333 struct ia64_vms_dynimgrela imgrela;
9334 Elf_Internal_Dyn *entry;
9335 uint64_t strtab_off = 0;
9336 uint64_t strtab_sz = 0;
9337 char *strtab = NULL;
9338 bool res = true;
9340 memset (&fixup, 0, sizeof (fixup));
9341 memset (&imgrela, 0, sizeof (imgrela));
9343 /* Note: the order of the entries is specified by the OpenVMS specs. */
9344 for (entry = filedata->dynamic_section;
9345 entry < filedata->dynamic_section + filedata->dynamic_nent;
9346 entry++)
9348 switch (entry->d_tag)
9350 case DT_IA_64_VMS_STRTAB_OFFSET:
9351 strtab_off = entry->d_un.d_val;
9352 break;
9353 case DT_STRSZ:
9354 strtab_sz = entry->d_un.d_val;
9355 if (strtab == NULL)
9356 strtab = get_data (NULL, filedata,
9357 filedata->dynamic_addr + strtab_off,
9358 1, strtab_sz, _("dynamic string section"));
9359 if (strtab == NULL)
9360 strtab_sz = 0;
9361 break;
9363 case DT_IA_64_VMS_NEEDED_IDENT:
9364 fixup.needed_ident = entry->d_un.d_val;
9365 break;
9366 case DT_NEEDED:
9367 fixup.needed = entry->d_un.d_val;
9368 break;
9369 case DT_IA_64_VMS_FIXUP_NEEDED:
9370 fixup.fixup_needed = entry->d_un.d_val;
9371 break;
9372 case DT_IA_64_VMS_FIXUP_RELA_CNT:
9373 fixup.fixup_rela_cnt = entry->d_un.d_val;
9374 break;
9375 case DT_IA_64_VMS_FIXUP_RELA_OFF:
9376 fixup.fixup_rela_off = entry->d_un.d_val;
9377 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
9378 res = false;
9379 break;
9380 case DT_IA_64_VMS_IMG_RELA_CNT:
9381 imgrela.img_rela_cnt = entry->d_un.d_val;
9382 break;
9383 case DT_IA_64_VMS_IMG_RELA_OFF:
9384 imgrela.img_rela_off = entry->d_un.d_val;
9385 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
9386 res = false;
9387 break;
9389 default:
9390 break;
9394 free (strtab);
9396 return res;
9399 static struct
9401 const char * name;
9402 int reloc;
9403 int size;
9404 relocation_type rel_type;
9406 dynamic_relocations [] =
9408 { "REL", DT_REL, DT_RELSZ, reltype_rel },
9409 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
9410 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
9411 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
9414 static relocation_type
9415 rel_type_from_sh_type (unsigned int sh_type)
9417 switch (sh_type)
9419 case SHT_RELA: return reltype_rela;
9420 case SHT_REL: return reltype_rel;
9421 case SHT_RELR: return reltype_relr;
9422 default: return reltype_unknown;
9426 static bool
9427 display_relocations (Elf_Internal_Shdr * section,
9428 Filedata * filedata)
9430 relocation_type rel_type = rel_type_from_sh_type (section->sh_type);
9432 if (rel_type == reltype_unknown)
9433 return false;
9435 uint64_t rel_size = section->sh_size;
9437 if (rel_size == 0)
9438 return false;
9440 if (filedata->is_separate)
9441 printf (_("\nIn linked file '%s' relocation section "),
9442 printable_string (filedata->file_name, 0));
9443 else
9444 printf (_("\nRelocation section "));
9446 if (filedata->string_table == NULL)
9447 printf ("%d", section->sh_name);
9448 else
9449 printf ("'%s'", printable_section_name (filedata, section));
9451 uint64_t num_rela = rel_size / section->sh_entsize;
9452 uint64_t rel_offset = section->sh_offset;
9454 if (rel_type == reltype_relr)
9456 /* Just stating the 'number of entries' in a RELR section can be
9457 misleading, since this is not the number of locations relocated, but
9458 the number of words in the compressed RELR format. So also provide
9459 the number of locations affected. */
9461 uint64_t num_reloc = count_relr_relocations (filedata, section);
9463 printf (_(" at offset %#" PRIx64), rel_offset);
9464 printf (ngettext (" contains %" PRIu64 " entry which relocates",
9465 " contains %" PRIu64 " entries which relocate",
9466 num_rela), num_rela);
9467 printf (ngettext (" %" PRIu64 " location:\n",
9468 " %" PRIu64 " locations:\n",
9469 num_reloc), num_reloc);
9471 else
9473 printf (ngettext (" at offset %#" PRIx64
9474 " contains %" PRIu64 " entry:\n",
9475 " at offset %#" PRIx64
9476 " contains %" PRIu64 " entries:\n",
9477 num_rela),
9478 rel_offset, num_rela);
9481 Elf_Internal_Shdr * symsec;
9482 Elf_Internal_Sym * symtab = NULL;
9483 uint64_t nsyms = 0;
9484 uint64_t strtablen = 0;
9485 char * strtab = NULL;
9487 if (section->sh_link == 0
9488 || section->sh_link >= filedata->file_header.e_shnum)
9490 /* Symbol data not available.
9491 This can happen, especially with RELR relocs.
9492 See if there is a .symtab section present.
9493 If so then use it. */
9494 symsec = find_section_by_name (filedata, ".symtab");
9496 else
9498 symsec = filedata->section_headers + section->sh_link;
9500 if (symsec->sh_type != SHT_SYMTAB
9501 && symsec->sh_type != SHT_DYNSYM)
9502 return false;
9505 if (symsec != NULL
9506 && !get_symtab (filedata, symsec, &symtab, &nsyms, &strtab, &strtablen))
9507 return false;
9509 bool res;
9511 if (rel_type == reltype_relr)
9512 res = dump_relr_relocations (filedata, section, symtab, nsyms, strtab, strtablen);
9513 else
9514 res = dump_relocations (filedata, rel_offset, rel_size,
9515 symtab, nsyms, strtab, strtablen,
9516 rel_type,
9517 symsec == NULL ? false : symsec->sh_type == SHT_DYNSYM);
9518 free (strtab);
9519 free (symtab);
9521 return res;
9524 /* Process the reloc section. */
9526 static bool
9527 process_relocs (Filedata * filedata)
9529 uint64_t rel_size;
9530 uint64_t rel_offset;
9532 if (!do_reloc)
9533 return true;
9535 if (do_using_dynamic)
9537 relocation_type rel_type;
9538 const char * name;
9539 bool has_dynamic_reloc;
9540 unsigned int i;
9542 has_dynamic_reloc = false;
9544 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
9546 rel_type = dynamic_relocations [i].rel_type;
9547 name = dynamic_relocations [i].name;
9548 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
9549 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
9551 if (rel_size)
9552 has_dynamic_reloc = true;
9554 if (rel_type == reltype_unknown)
9556 if (dynamic_relocations [i].reloc == DT_JMPREL)
9557 switch (filedata->dynamic_info[DT_PLTREL])
9559 case DT_REL:
9560 rel_type = reltype_rel;
9561 break;
9562 case DT_RELA:
9563 rel_type = reltype_rela;
9564 break;
9568 if (rel_size)
9570 if (filedata->is_separate)
9571 printf
9572 (_("\nIn linked file '%s' section '%s' at offset %#" PRIx64
9573 " contains %" PRId64 " bytes:\n"),
9574 filedata->file_name, name, rel_offset, rel_size);
9575 else
9576 printf
9577 (_("\n'%s' relocation section at offset %#" PRIx64
9578 " contains %" PRId64 " bytes:\n"),
9579 name, rel_offset, rel_size);
9581 dump_relocations (filedata,
9582 offset_from_vma (filedata, rel_offset, rel_size),
9583 rel_size,
9584 filedata->dynamic_symbols,
9585 filedata->num_dynamic_syms,
9586 filedata->dynamic_strings,
9587 filedata->dynamic_strings_length,
9588 rel_type, true /* is_dynamic */);
9592 if (is_ia64_vms (filedata))
9593 if (process_ia64_vms_dynamic_relocs (filedata))
9594 has_dynamic_reloc = true;
9596 if (! has_dynamic_reloc)
9598 if (filedata->is_separate)
9599 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
9600 filedata->file_name);
9601 else
9602 printf (_("\nThere are no dynamic relocations in this file.\n"));
9605 else
9607 Elf_Internal_Shdr * section;
9608 size_t i;
9609 bool found = false;
9611 for (i = 0, section = filedata->section_headers;
9612 i < filedata->file_header.e_shnum;
9613 i++, section++)
9615 if (display_relocations (section, filedata))
9616 found = true;
9619 if (! found)
9621 /* Users sometimes forget the -D option, so try to be helpful. */
9622 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
9624 if (filedata->dynamic_info[dynamic_relocations [i].size])
9626 if (filedata->is_separate)
9627 printf (_("\nThere are no static relocations in linked file '%s'."),
9628 filedata->file_name);
9629 else
9630 printf (_("\nThere are no static relocations in this file."));
9631 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
9633 break;
9636 if (i == ARRAY_SIZE (dynamic_relocations))
9638 if (filedata->is_separate)
9639 printf (_("\nThere are no relocations in linked file '%s'.\n"),
9640 filedata->file_name);
9641 else
9642 printf (_("\nThere are no relocations in this file.\n"));
9647 return true;
9650 /* An absolute address consists of a section and an offset. If the
9651 section is NULL, the offset itself is the address, otherwise, the
9652 address equals to LOAD_ADDRESS(section) + offset. */
9654 struct absaddr
9656 unsigned short section;
9657 uint64_t offset;
9660 /* Find the nearest symbol at or below ADDR. Returns the symbol
9661 name, if found, and the offset from the symbol to ADDR. */
9663 static void
9664 find_symbol_for_address (Filedata *filedata,
9665 Elf_Internal_Sym *symtab,
9666 uint64_t nsyms,
9667 const char *strtab,
9668 uint64_t strtab_size,
9669 struct absaddr addr,
9670 const char **symname,
9671 uint64_t *offset)
9673 uint64_t dist = 0x100000;
9674 Elf_Internal_Sym * sym;
9675 Elf_Internal_Sym * beg;
9676 Elf_Internal_Sym * end;
9677 Elf_Internal_Sym * best = NULL;
9679 REMOVE_ARCH_BITS (addr.offset);
9680 beg = symtab;
9681 end = symtab + nsyms;
9683 while (beg < end)
9685 uint64_t value;
9687 sym = beg + (end - beg) / 2;
9689 value = sym->st_value;
9690 REMOVE_ARCH_BITS (value);
9692 if (sym->st_name != 0
9693 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
9694 && addr.offset >= value
9695 && addr.offset - value < dist)
9697 best = sym;
9698 dist = addr.offset - value;
9699 if (!dist)
9700 break;
9703 if (addr.offset < value)
9704 end = sym;
9705 else
9706 beg = sym + 1;
9709 if (best)
9711 *symname = (best->st_name >= strtab_size
9712 ? _("<corrupt>") : strtab + best->st_name);
9713 *offset = dist;
9714 return;
9717 *symname = NULL;
9718 *offset = addr.offset;
9721 /* Process the unwind section. */
9723 #include "unwind-ia64.h"
9725 struct ia64_unw_table_entry
9727 struct absaddr start;
9728 struct absaddr end;
9729 struct absaddr info;
9732 struct ia64_unw_aux_info
9734 struct ia64_unw_table_entry * table; /* Unwind table. */
9735 uint64_t table_len; /* Length of unwind table. */
9736 unsigned char * info; /* Unwind info. */
9737 uint64_t info_size; /* Size of unwind info. */
9738 uint64_t info_addr; /* Starting address of unwind info. */
9739 uint64_t seg_base; /* Starting address of segment. */
9740 Elf_Internal_Sym * symtab; /* The symbol table. */
9741 uint64_t nsyms; /* Number of symbols. */
9742 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9743 uint64_t nfuns; /* Number of entries in funtab. */
9744 char * strtab; /* The string table. */
9745 uint64_t strtab_size; /* Size of string table. */
9748 static bool
9749 dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
9751 struct ia64_unw_table_entry * tp;
9752 size_t j, nfuns;
9753 int in_body;
9754 bool res = true;
9756 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9757 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9758 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9759 aux->funtab[nfuns++] = aux->symtab[j];
9760 aux->nfuns = nfuns;
9761 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9763 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9765 uint64_t stamp;
9766 uint64_t offset;
9767 const unsigned char * dp;
9768 const unsigned char * head;
9769 const unsigned char * end;
9770 const char * procname;
9772 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
9773 aux->strtab_size, tp->start, &procname, &offset);
9775 fputs ("\n<", stdout);
9777 if (procname)
9779 fputs (procname, stdout);
9781 if (offset)
9782 printf ("+%" PRIx64, offset);
9785 fputs (">: [", stdout);
9786 print_vma (tp->start.offset, PREFIX_HEX);
9787 fputc ('-', stdout);
9788 print_vma (tp->end.offset, PREFIX_HEX);
9789 printf ("], info at +0x%" PRIx64 "\n",
9790 tp->info.offset - aux->seg_base);
9792 /* PR 17531: file: 86232b32. */
9793 if (aux->info == NULL)
9794 continue;
9796 offset = tp->info.offset;
9797 if (tp->info.section)
9799 if (tp->info.section >= filedata->file_header.e_shnum)
9801 warn (_("Invalid section %u in table entry %td\n"),
9802 tp->info.section, tp - aux->table);
9803 res = false;
9804 continue;
9806 offset += filedata->section_headers[tp->info.section].sh_addr;
9808 offset -= aux->info_addr;
9809 /* PR 17531: file: 0997b4d1. */
9810 if (offset >= aux->info_size
9811 || aux->info_size - offset < 8)
9813 warn (_("Invalid offset %" PRIx64 " in table entry %td\n"),
9814 tp->info.offset, tp - aux->table);
9815 res = false;
9816 continue;
9819 head = aux->info + offset;
9820 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
9822 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
9823 (unsigned) UNW_VER (stamp),
9824 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
9825 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
9826 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
9827 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
9829 if (UNW_VER (stamp) != 1)
9831 printf (_("\tUnknown version.\n"));
9832 continue;
9835 in_body = 0;
9836 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
9837 /* PR 17531: file: 16ceda89. */
9838 if (end > aux->info + aux->info_size)
9839 end = aux->info + aux->info_size;
9840 for (dp = head + 8; dp < end;)
9841 dp = unw_decode (dp, in_body, & in_body, end);
9844 free (aux->funtab);
9846 return res;
9849 static bool
9850 slurp_ia64_unwind_table (Filedata * filedata,
9851 struct ia64_unw_aux_info * aux,
9852 Elf_Internal_Shdr * sec)
9854 uint64_t size, nrelas, i;
9855 Elf_Internal_Phdr * seg;
9856 struct ia64_unw_table_entry * tep;
9857 Elf_Internal_Shdr * relsec;
9858 Elf_Internal_Rela * rela;
9859 Elf_Internal_Rela * rp;
9860 unsigned char * table;
9861 unsigned char * tp;
9862 Elf_Internal_Sym * sym;
9863 const char * relname;
9865 aux->table_len = 0;
9867 /* First, find the starting address of the segment that includes
9868 this section: */
9870 if (filedata->file_header.e_phnum)
9872 if (! get_program_headers (filedata))
9873 return false;
9875 for (seg = filedata->program_headers;
9876 seg < filedata->program_headers + filedata->file_header.e_phnum;
9877 ++seg)
9879 if (seg->p_type != PT_LOAD)
9880 continue;
9882 if (sec->sh_addr >= seg->p_vaddr
9883 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9885 aux->seg_base = seg->p_vaddr;
9886 break;
9891 /* Second, build the unwind table from the contents of the unwind section: */
9892 size = sec->sh_size;
9893 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
9894 _("unwind table"));
9895 if (!table)
9896 return false;
9898 aux->table_len = size / (3 * eh_addr_size);
9899 aux->table = (struct ia64_unw_table_entry *)
9900 xcmalloc (aux->table_len, sizeof (aux->table[0]));
9901 tep = aux->table;
9903 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
9905 tep->start.section = SHN_UNDEF;
9906 tep->end.section = SHN_UNDEF;
9907 tep->info.section = SHN_UNDEF;
9908 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9909 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9910 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9911 tep->start.offset += aux->seg_base;
9912 tep->end.offset += aux->seg_base;
9913 tep->info.offset += aux->seg_base;
9915 free (table);
9917 /* Third, apply any relocations to the unwind table: */
9918 for (relsec = filedata->section_headers;
9919 relsec < filedata->section_headers + filedata->file_header.e_shnum;
9920 ++relsec)
9922 if (relsec->sh_type != SHT_RELA
9923 || relsec->sh_info >= filedata->file_header.e_shnum
9924 || filedata->section_headers + relsec->sh_info != sec)
9925 continue;
9927 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
9928 & rela, & nrelas))
9930 free (aux->table);
9931 aux->table = NULL;
9932 aux->table_len = 0;
9933 return false;
9936 for (rp = rela; rp < rela + nrelas; ++rp)
9938 unsigned int sym_ndx;
9939 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9940 relname = elf_ia64_reloc_type (r_type);
9942 /* PR 17531: file: 9fa67536. */
9943 if (relname == NULL)
9945 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9946 continue;
9949 if (! startswith (relname, "R_IA64_SEGREL"))
9951 warn (_("Skipping unexpected relocation type: %s\n"), relname);
9952 continue;
9955 i = rp->r_offset / (3 * eh_addr_size);
9957 /* PR 17531: file: 5bc8d9bf. */
9958 if (i >= aux->table_len)
9960 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9962 continue;
9965 sym_ndx = get_reloc_symindex (rp->r_info);
9966 if (sym_ndx >= aux->nsyms)
9968 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9969 sym_ndx);
9970 continue;
9972 sym = aux->symtab + sym_ndx;
9974 switch (rp->r_offset / eh_addr_size % 3)
9976 case 0:
9977 aux->table[i].start.section = sym->st_shndx;
9978 aux->table[i].start.offset = rp->r_addend + sym->st_value;
9979 break;
9980 case 1:
9981 aux->table[i].end.section = sym->st_shndx;
9982 aux->table[i].end.offset = rp->r_addend + sym->st_value;
9983 break;
9984 case 2:
9985 aux->table[i].info.section = sym->st_shndx;
9986 aux->table[i].info.offset = rp->r_addend + sym->st_value;
9987 break;
9988 default:
9989 break;
9993 free (rela);
9996 return true;
9999 static bool
10000 ia64_process_unwind (Filedata * filedata)
10002 Elf_Internal_Shdr * sec;
10003 Elf_Internal_Shdr * unwsec = NULL;
10004 uint64_t i, unwcount = 0, unwstart = 0;
10005 struct ia64_unw_aux_info aux;
10006 bool res = true;
10008 memset (& aux, 0, sizeof (aux));
10010 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
10012 if (sec->sh_type == SHT_SYMTAB)
10014 if (aux.symtab)
10016 error (_("Multiple symbol tables encountered\n"));
10017 free (aux.symtab);
10018 aux.symtab = NULL;
10019 free (aux.strtab);
10020 aux.strtab = NULL;
10022 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10023 &aux.strtab, &aux.strtab_size))
10024 return false;
10026 else if (sec->sh_type == SHT_IA_64_UNWIND)
10027 unwcount++;
10030 if (!unwcount)
10031 printf (_("\nThere are no unwind sections in this file.\n"));
10033 while (unwcount-- > 0)
10035 const char *suffix;
10036 size_t len, len2;
10038 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
10039 i < filedata->file_header.e_shnum; ++i, ++sec)
10040 if (sec->sh_type == SHT_IA_64_UNWIND)
10042 unwsec = sec;
10043 break;
10045 /* We have already counted the number of SHT_IA64_UNWIND
10046 sections so the loop above should never fail. */
10047 assert (unwsec != NULL);
10049 unwstart = i + 1;
10050 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
10052 if ((unwsec->sh_flags & SHF_GROUP) != 0)
10054 /* We need to find which section group it is in. */
10055 struct group_list * g;
10057 if (filedata->section_headers_groups == NULL
10058 || filedata->section_headers_groups[i] == NULL)
10059 i = filedata->file_header.e_shnum;
10060 else
10062 g = filedata->section_headers_groups[i]->root;
10064 for (; g != NULL; g = g->next)
10066 sec = filedata->section_headers + g->section_index;
10068 if (section_name_valid (filedata, sec)
10069 && streq (section_name (filedata, sec),
10070 ELF_STRING_ia64_unwind_info))
10071 break;
10074 if (g == NULL)
10075 i = filedata->file_header.e_shnum;
10078 else if (section_name_valid (filedata, unwsec)
10079 && startswith (section_name (filedata, unwsec),
10080 ELF_STRING_ia64_unwind_once))
10082 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
10083 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
10084 suffix = section_name (filedata, unwsec) + len;
10085 for (i = 0, sec = filedata->section_headers;
10086 i < filedata->file_header.e_shnum;
10087 ++i, ++sec)
10088 if (section_name_valid (filedata, sec)
10089 && startswith (section_name (filedata, sec),
10090 ELF_STRING_ia64_unwind_info_once)
10091 && streq (section_name (filedata, sec) + len2, suffix))
10092 break;
10094 else
10096 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
10097 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
10098 len = sizeof (ELF_STRING_ia64_unwind) - 1;
10099 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
10100 suffix = "";
10101 if (section_name_valid (filedata, unwsec)
10102 && startswith (section_name (filedata, unwsec),
10103 ELF_STRING_ia64_unwind))
10104 suffix = section_name (filedata, unwsec) + len;
10105 for (i = 0, sec = filedata->section_headers;
10106 i < filedata->file_header.e_shnum;
10107 ++i, ++sec)
10108 if (section_name_valid (filedata, sec)
10109 && startswith (section_name (filedata, sec),
10110 ELF_STRING_ia64_unwind_info)
10111 && streq (section_name (filedata, sec) + len2, suffix))
10112 break;
10115 if (i == filedata->file_header.e_shnum)
10117 printf (_("\nCould not find unwind info section for "));
10119 if (filedata->string_table == NULL)
10120 printf ("%d", unwsec->sh_name);
10121 else
10122 printf ("'%s'", printable_section_name (filedata, unwsec));
10124 else
10126 aux.info_addr = sec->sh_addr;
10127 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
10128 sec->sh_size,
10129 _("unwind info"));
10130 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
10132 printf (_("\nUnwind section "));
10134 if (filedata->string_table == NULL)
10135 printf ("%d", unwsec->sh_name);
10136 else
10137 printf ("'%s'", printable_section_name (filedata, unwsec));
10139 printf (_(" at offset %#" PRIx64 " contains %" PRIu64 " entries:\n"),
10140 unwsec->sh_offset,
10141 unwsec->sh_size / (3 * eh_addr_size));
10143 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
10144 && aux.table_len > 0)
10145 dump_ia64_unwind (filedata, & aux);
10147 free ((char *) aux.table);
10148 free ((char *) aux.info);
10149 aux.table = NULL;
10150 aux.info = NULL;
10154 free (aux.symtab);
10155 free ((char *) aux.strtab);
10157 return res;
10160 struct hppa_unw_table_entry
10162 struct absaddr start;
10163 struct absaddr end;
10164 unsigned int Cannot_unwind:1; /* 0 */
10165 unsigned int Millicode:1; /* 1 */
10166 unsigned int Millicode_save_sr0:1; /* 2 */
10167 unsigned int Region_description:2; /* 3..4 */
10168 unsigned int reserved1:1; /* 5 */
10169 unsigned int Entry_SR:1; /* 6 */
10170 unsigned int Entry_FR:4; /* Number saved 7..10 */
10171 unsigned int Entry_GR:5; /* Number saved 11..15 */
10172 unsigned int Args_stored:1; /* 16 */
10173 unsigned int Variable_Frame:1; /* 17 */
10174 unsigned int Separate_Package_Body:1; /* 18 */
10175 unsigned int Frame_Extension_Millicode:1; /* 19 */
10176 unsigned int Stack_Overflow_Check:1; /* 20 */
10177 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
10178 unsigned int Ada_Region:1; /* 22 */
10179 unsigned int cxx_info:1; /* 23 */
10180 unsigned int cxx_try_catch:1; /* 24 */
10181 unsigned int sched_entry_seq:1; /* 25 */
10182 unsigned int reserved2:1; /* 26 */
10183 unsigned int Save_SP:1; /* 27 */
10184 unsigned int Save_RP:1; /* 28 */
10185 unsigned int Save_MRP_in_frame:1; /* 29 */
10186 unsigned int extn_ptr_defined:1; /* 30 */
10187 unsigned int Cleanup_defined:1; /* 31 */
10189 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
10190 unsigned int HP_UX_interrupt_marker:1; /* 1 */
10191 unsigned int Large_frame:1; /* 2 */
10192 unsigned int Pseudo_SP_Set:1; /* 3 */
10193 unsigned int reserved4:1; /* 4 */
10194 unsigned int Total_frame_size:27; /* 5..31 */
10197 struct hppa_unw_aux_info
10199 struct hppa_unw_table_entry * table; /* Unwind table. */
10200 uint64_t table_len; /* Length of unwind table. */
10201 uint64_t seg_base; /* Starting address of segment. */
10202 Elf_Internal_Sym * symtab; /* The symbol table. */
10203 uint64_t nsyms; /* Number of symbols. */
10204 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
10205 uint64_t nfuns; /* Number of entries in funtab. */
10206 char * strtab; /* The string table. */
10207 uint64_t strtab_size; /* Size of string table. */
10210 static bool
10211 dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
10213 struct hppa_unw_table_entry * tp;
10214 uint64_t j, nfuns;
10215 bool res = true;
10217 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10218 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10219 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10220 aux->funtab[nfuns++] = aux->symtab[j];
10221 aux->nfuns = nfuns;
10222 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10224 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
10226 uint64_t offset;
10227 const char * procname;
10229 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
10230 aux->strtab_size, tp->start, &procname,
10231 &offset);
10233 fputs ("\n<", stdout);
10235 if (procname)
10237 fputs (procname, stdout);
10239 if (offset)
10240 printf ("+%" PRIx64, offset);
10243 fputs (">: [", stdout);
10244 print_vma (tp->start.offset, PREFIX_HEX);
10245 fputc ('-', stdout);
10246 print_vma (tp->end.offset, PREFIX_HEX);
10247 printf ("]\n\t");
10249 #define PF(_m) if (tp->_m) printf (#_m " ");
10250 #define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
10251 PF(Cannot_unwind);
10252 PF(Millicode);
10253 PF(Millicode_save_sr0);
10254 /* PV(Region_description); */
10255 PF(Entry_SR);
10256 PV(Entry_FR);
10257 PV(Entry_GR);
10258 PF(Args_stored);
10259 PF(Variable_Frame);
10260 PF(Separate_Package_Body);
10261 PF(Frame_Extension_Millicode);
10262 PF(Stack_Overflow_Check);
10263 PF(Two_Instruction_SP_Increment);
10264 PF(Ada_Region);
10265 PF(cxx_info);
10266 PF(cxx_try_catch);
10267 PF(sched_entry_seq);
10268 PF(Save_SP);
10269 PF(Save_RP);
10270 PF(Save_MRP_in_frame);
10271 PF(extn_ptr_defined);
10272 PF(Cleanup_defined);
10273 PF(MPE_XL_interrupt_marker);
10274 PF(HP_UX_interrupt_marker);
10275 PF(Large_frame);
10276 PF(Pseudo_SP_Set);
10277 PV(Total_frame_size);
10278 #undef PF
10279 #undef PV
10282 printf ("\n");
10284 free (aux->funtab);
10286 return res;
10289 static bool
10290 slurp_hppa_unwind_table (Filedata * filedata,
10291 struct hppa_unw_aux_info * aux,
10292 Elf_Internal_Shdr * sec)
10294 uint64_t size, unw_ent_size, nentries, nrelas, i;
10295 Elf_Internal_Phdr * seg;
10296 struct hppa_unw_table_entry * tep;
10297 Elf_Internal_Shdr * relsec;
10298 Elf_Internal_Rela * rela;
10299 Elf_Internal_Rela * rp;
10300 unsigned char * table;
10301 unsigned char * tp;
10302 Elf_Internal_Sym * sym;
10303 const char * relname;
10305 /* First, find the starting address of the segment that includes
10306 this section. */
10307 if (filedata->file_header.e_phnum)
10309 if (! get_program_headers (filedata))
10310 return false;
10312 for (seg = filedata->program_headers;
10313 seg < filedata->program_headers + filedata->file_header.e_phnum;
10314 ++seg)
10316 if (seg->p_type != PT_LOAD)
10317 continue;
10319 if (sec->sh_addr >= seg->p_vaddr
10320 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
10322 aux->seg_base = seg->p_vaddr;
10323 break;
10328 /* Second, build the unwind table from the contents of the unwind
10329 section. */
10330 size = sec->sh_size;
10331 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
10332 _("unwind table"));
10333 if (!table)
10334 return false;
10336 unw_ent_size = 16;
10337 nentries = size / unw_ent_size;
10338 size = unw_ent_size * nentries;
10340 aux->table_len = nentries;
10341 tep = aux->table = (struct hppa_unw_table_entry *)
10342 xcmalloc (nentries, sizeof (aux->table[0]));
10344 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
10346 unsigned int tmp1, tmp2;
10348 tep->start.section = SHN_UNDEF;
10349 tep->end.section = SHN_UNDEF;
10351 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
10352 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
10353 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
10354 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
10356 tep->start.offset += aux->seg_base;
10357 tep->end.offset += aux->seg_base;
10359 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
10360 tep->Millicode = (tmp1 >> 30) & 0x1;
10361 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
10362 tep->Region_description = (tmp1 >> 27) & 0x3;
10363 tep->reserved1 = (tmp1 >> 26) & 0x1;
10364 tep->Entry_SR = (tmp1 >> 25) & 0x1;
10365 tep->Entry_FR = (tmp1 >> 21) & 0xf;
10366 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
10367 tep->Args_stored = (tmp1 >> 15) & 0x1;
10368 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
10369 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
10370 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
10371 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
10372 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
10373 tep->Ada_Region = (tmp1 >> 9) & 0x1;
10374 tep->cxx_info = (tmp1 >> 8) & 0x1;
10375 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
10376 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
10377 tep->reserved2 = (tmp1 >> 5) & 0x1;
10378 tep->Save_SP = (tmp1 >> 4) & 0x1;
10379 tep->Save_RP = (tmp1 >> 3) & 0x1;
10380 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
10381 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
10382 tep->Cleanup_defined = tmp1 & 0x1;
10384 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
10385 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
10386 tep->Large_frame = (tmp2 >> 29) & 0x1;
10387 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
10388 tep->reserved4 = (tmp2 >> 27) & 0x1;
10389 tep->Total_frame_size = tmp2 & 0x7ffffff;
10391 free (table);
10393 /* Third, apply any relocations to the unwind table. */
10394 for (relsec = filedata->section_headers;
10395 relsec < filedata->section_headers + filedata->file_header.e_shnum;
10396 ++relsec)
10398 if (relsec->sh_type != SHT_RELA
10399 || relsec->sh_info >= filedata->file_header.e_shnum
10400 || filedata->section_headers + relsec->sh_info != sec)
10401 continue;
10403 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
10404 & rela, & nrelas))
10405 return false;
10407 for (rp = rela; rp < rela + nrelas; ++rp)
10409 unsigned int sym_ndx;
10410 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
10411 relname = elf_hppa_reloc_type (r_type);
10413 if (relname == NULL)
10415 warn (_("Skipping unknown relocation type: %u\n"), r_type);
10416 continue;
10419 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
10420 if (! startswith (relname, "R_PARISC_SEGREL"))
10422 warn (_("Skipping unexpected relocation type: %s\n"), relname);
10423 continue;
10426 i = rp->r_offset / unw_ent_size;
10427 if (i >= aux->table_len)
10429 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
10431 continue;
10434 sym_ndx = get_reloc_symindex (rp->r_info);
10435 if (sym_ndx >= aux->nsyms)
10437 warn (_("Skipping reloc with invalid symbol index: %u\n"),
10438 sym_ndx);
10439 continue;
10441 sym = aux->symtab + sym_ndx;
10443 switch ((rp->r_offset % unw_ent_size) / 4)
10445 case 0:
10446 aux->table[i].start.section = sym->st_shndx;
10447 aux->table[i].start.offset = sym->st_value + rp->r_addend;
10448 break;
10449 case 1:
10450 aux->table[i].end.section = sym->st_shndx;
10451 aux->table[i].end.offset = sym->st_value + rp->r_addend;
10452 break;
10453 default:
10454 break;
10458 free (rela);
10461 return true;
10464 static bool
10465 hppa_process_unwind (Filedata * filedata)
10467 struct hppa_unw_aux_info aux;
10468 Elf_Internal_Shdr * unwsec = NULL;
10469 Elf_Internal_Shdr * sec;
10470 size_t i;
10471 bool res = true;
10473 if (filedata->string_table == NULL)
10474 return false;
10476 memset (& aux, 0, sizeof (aux));
10478 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
10480 if (sec->sh_type == SHT_SYMTAB)
10482 if (aux.symtab)
10484 error (_("Multiple symbol tables encountered\n"));
10485 free (aux.symtab);
10486 aux.symtab = NULL;
10487 free (aux.strtab);
10488 aux.strtab = NULL;
10490 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10491 &aux.strtab, &aux.strtab_size))
10492 return false;
10494 else if (section_name_valid (filedata, sec)
10495 && streq (section_name (filedata, sec), ".PARISC.unwind"))
10496 unwsec = sec;
10499 if (!unwsec)
10500 printf (_("\nThere are no unwind sections in this file.\n"));
10502 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
10504 if (section_name_valid (filedata, sec)
10505 && streq (section_name (filedata, sec), ".PARISC.unwind"))
10507 uint64_t num_unwind = sec->sh_size / 16;
10509 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
10510 "contains %" PRIu64 " entry:\n",
10511 "\nUnwind section '%s' at offset %#" PRIx64 " "
10512 "contains %" PRIu64 " entries:\n",
10513 num_unwind),
10514 printable_section_name (filedata, sec),
10515 sec->sh_offset,
10516 num_unwind);
10518 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
10519 res = false;
10521 if (res && aux.table_len > 0)
10523 if (! dump_hppa_unwind (filedata, &aux))
10524 res = false;
10527 free ((char *) aux.table);
10528 aux.table = NULL;
10532 free (aux.symtab);
10533 free ((char *) aux.strtab);
10535 return res;
10538 struct arm_section
10540 unsigned char * data; /* The unwind data. */
10541 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
10542 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
10543 uint64_t nrelas; /* The number of relocations. */
10544 unsigned int rel_type; /* REL or RELA ? */
10545 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
10548 struct arm_unw_aux_info
10550 Filedata * filedata; /* The file containing the unwind sections. */
10551 Elf_Internal_Sym * symtab; /* The file's symbol table. */
10552 uint64_t nsyms; /* Number of symbols. */
10553 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
10554 uint64_t nfuns; /* Number of these symbols. */
10555 char * strtab; /* The file's string table. */
10556 uint64_t strtab_size; /* Size of string table. */
10559 static const char *
10560 arm_print_vma_and_name (Filedata * filedata,
10561 struct arm_unw_aux_info * aux,
10562 uint64_t fn,
10563 struct absaddr addr)
10565 const char *procname;
10566 uint64_t sym_offset;
10568 if (addr.section == SHN_UNDEF)
10569 addr.offset = fn;
10571 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
10572 aux->strtab_size, addr, &procname,
10573 &sym_offset);
10575 print_vma (fn, PREFIX_HEX);
10577 if (procname)
10579 fputs (" <", stdout);
10580 fputs (procname, stdout);
10582 if (sym_offset)
10583 printf ("+0x%" PRIx64, sym_offset);
10584 fputc ('>', stdout);
10587 return procname;
10590 static void
10591 arm_free_section (struct arm_section *arm_sec)
10593 free (arm_sec->data);
10594 free (arm_sec->rela);
10597 /* 1) If SEC does not match the one cached in ARM_SEC, then free the current
10598 cached section and install SEC instead.
10599 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
10600 and return its valued in * WORDP, relocating if necessary.
10601 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
10602 relocation's offset in ADDR.
10603 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
10604 into the string table of the symbol associated with the reloc. If no
10605 reloc was applied store -1 there.
10606 5) Return TRUE upon success, FALSE otherwise. */
10608 static bool
10609 get_unwind_section_word (Filedata * filedata,
10610 struct arm_unw_aux_info * aux,
10611 struct arm_section * arm_sec,
10612 Elf_Internal_Shdr * sec,
10613 uint64_t word_offset,
10614 unsigned int * wordp,
10615 struct absaddr * addr,
10616 uint64_t * sym_name)
10618 Elf_Internal_Rela *rp;
10619 Elf_Internal_Sym *sym;
10620 const char * relname;
10621 unsigned int word;
10622 bool wrapped;
10624 if (sec == NULL || arm_sec == NULL)
10625 return false;
10627 addr->section = SHN_UNDEF;
10628 addr->offset = 0;
10630 if (sym_name != NULL)
10631 *sym_name = (uint64_t) -1;
10633 /* If necessary, update the section cache. */
10634 if (sec != arm_sec->sec)
10636 Elf_Internal_Shdr *relsec;
10638 arm_free_section (arm_sec);
10640 arm_sec->sec = sec;
10641 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
10642 sec->sh_size, _("unwind data"));
10643 arm_sec->rela = NULL;
10644 arm_sec->nrelas = 0;
10646 for (relsec = filedata->section_headers;
10647 relsec < filedata->section_headers + filedata->file_header.e_shnum;
10648 ++relsec)
10650 if (relsec->sh_info >= filedata->file_header.e_shnum
10651 || filedata->section_headers + relsec->sh_info != sec
10652 /* PR 15745: Check the section type as well. */
10653 || (relsec->sh_type != SHT_REL
10654 && relsec->sh_type != SHT_RELA))
10655 continue;
10657 arm_sec->rel_type = relsec->sh_type;
10658 if (relsec->sh_type == SHT_REL)
10660 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
10661 relsec->sh_size,
10662 & arm_sec->rela, & arm_sec->nrelas))
10663 return false;
10665 else /* relsec->sh_type == SHT_RELA */
10667 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
10668 relsec->sh_size,
10669 & arm_sec->rela, & arm_sec->nrelas))
10670 return false;
10672 break;
10675 arm_sec->next_rela = arm_sec->rela;
10678 /* If there is no unwind data we can do nothing. */
10679 if (arm_sec->data == NULL)
10680 return false;
10682 /* If the offset is invalid then fail. */
10683 if (/* PR 21343 *//* PR 18879 */
10684 sec->sh_size < 4
10685 || word_offset > sec->sh_size - 4)
10686 return false;
10688 /* Get the word at the required offset. */
10689 word = byte_get (arm_sec->data + word_offset, 4);
10691 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
10692 if (arm_sec->rela == NULL)
10694 * wordp = word;
10695 return true;
10698 /* Look through the relocs to find the one that applies to the provided offset. */
10699 wrapped = false;
10700 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
10702 uint64_t prelval, offset;
10704 if (rp->r_offset > word_offset && !wrapped)
10706 rp = arm_sec->rela;
10707 wrapped = true;
10709 if (rp->r_offset > word_offset)
10710 break;
10712 if (rp->r_offset & 3)
10714 warn (_("Skipping unexpected relocation at offset %#" PRIx64 "\n"),
10715 rp->r_offset);
10716 continue;
10719 if (rp->r_offset < word_offset)
10720 continue;
10722 /* PR 17531: file: 027-161405-0.004 */
10723 if (aux->symtab == NULL)
10724 continue;
10726 if (arm_sec->rel_type == SHT_REL)
10728 offset = word & 0x7fffffff;
10729 if (offset & 0x40000000)
10730 offset |= ~ (uint64_t) 0x7fffffff;
10732 else if (arm_sec->rel_type == SHT_RELA)
10733 offset = rp->r_addend;
10734 else
10736 error (_("Unknown section relocation type %d encountered\n"),
10737 arm_sec->rel_type);
10738 break;
10741 /* PR 17531 file: 027-1241568-0.004. */
10742 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
10744 error (_("Bad symbol index in unwind relocation "
10745 "(%" PRIu64 " > %" PRIu64 ")\n"),
10746 ELF32_R_SYM (rp->r_info), aux->nsyms);
10747 break;
10750 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
10751 offset += sym->st_value;
10752 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
10754 /* Check that we are processing the expected reloc type. */
10755 if (filedata->file_header.e_machine == EM_ARM)
10757 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
10758 if (relname == NULL)
10760 warn (_("Skipping unknown ARM relocation type: %d\n"),
10761 (int) ELF32_R_TYPE (rp->r_info));
10762 continue;
10765 if (streq (relname, "R_ARM_NONE"))
10766 continue;
10768 if (! streq (relname, "R_ARM_PREL31"))
10770 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
10771 continue;
10774 else if (filedata->file_header.e_machine == EM_TI_C6000)
10776 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
10777 if (relname == NULL)
10779 warn (_("Skipping unknown C6000 relocation type: %d\n"),
10780 (int) ELF32_R_TYPE (rp->r_info));
10781 continue;
10784 if (streq (relname, "R_C6000_NONE"))
10785 continue;
10787 if (! streq (relname, "R_C6000_PREL31"))
10789 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
10790 continue;
10793 prelval >>= 1;
10795 else
10797 /* This function currently only supports ARM and TI unwinders. */
10798 warn (_("Only TI and ARM unwinders are currently supported\n"));
10799 break;
10802 word = (word & ~ (uint64_t) 0x7fffffff) | (prelval & 0x7fffffff);
10803 addr->section = sym->st_shndx;
10804 addr->offset = offset;
10806 if (sym_name)
10807 * sym_name = sym->st_name;
10808 break;
10811 *wordp = word;
10812 arm_sec->next_rela = rp;
10814 return true;
10817 static const char *tic6x_unwind_regnames[16] =
10819 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
10820 "A14", "A13", "A12", "A11", "A10",
10821 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
10824 static void
10825 decode_tic6x_unwind_regmask (unsigned int mask)
10827 int i;
10829 for (i = 12; mask; mask >>= 1, i--)
10831 if (mask & 1)
10833 fputs (tic6x_unwind_regnames[i], stdout);
10834 if (mask > 1)
10835 fputs (", ", stdout);
10840 #define ADVANCE \
10841 if (remaining == 0 && more_words) \
10843 data_offset += 4; \
10844 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
10845 data_offset, & word, & addr, NULL)) \
10846 return false; \
10847 remaining = 4; \
10848 more_words--; \
10851 #define GET_OP(OP) \
10852 ADVANCE; \
10853 if (remaining) \
10855 remaining--; \
10856 (OP) = word >> 24; \
10857 word <<= 8; \
10859 else \
10861 printf (_("[Truncated opcode]\n")); \
10862 return false; \
10864 printf ("0x%02x ", OP)
10866 static bool
10867 decode_arm_unwind_bytecode (Filedata * filedata,
10868 struct arm_unw_aux_info * aux,
10869 unsigned int word,
10870 unsigned int remaining,
10871 unsigned int more_words,
10872 uint64_t data_offset,
10873 Elf_Internal_Shdr * data_sec,
10874 struct arm_section * data_arm_sec)
10876 struct absaddr addr;
10877 bool res = true;
10879 /* Decode the unwinding instructions. */
10880 while (1)
10882 unsigned int op, op2;
10884 ADVANCE;
10885 if (remaining == 0)
10886 break;
10887 remaining--;
10888 op = word >> 24;
10889 word <<= 8;
10891 printf (" 0x%02x ", op);
10893 if ((op & 0xc0) == 0x00)
10895 int offset = ((op & 0x3f) << 2) + 4;
10897 printf (" vsp = vsp + %d", offset);
10899 else if ((op & 0xc0) == 0x40)
10901 int offset = ((op & 0x3f) << 2) + 4;
10903 printf (" vsp = vsp - %d", offset);
10905 else if ((op & 0xf0) == 0x80)
10907 GET_OP (op2);
10908 if (op == 0x80 && op2 == 0)
10909 printf (_("Refuse to unwind"));
10910 else
10912 unsigned int mask = ((op & 0x0f) << 8) | op2;
10913 bool first = true;
10914 int i;
10916 printf ("pop {");
10917 for (i = 0; i < 12; i++)
10918 if (mask & (1 << i))
10920 if (first)
10921 first = false;
10922 else
10923 printf (", ");
10924 printf ("r%d", 4 + i);
10926 printf ("}");
10929 else if ((op & 0xf0) == 0x90)
10931 if (op == 0x9d || op == 0x9f)
10932 printf (_(" [Reserved]"));
10933 else
10934 printf (" vsp = r%d", op & 0x0f);
10936 else if ((op & 0xf0) == 0xa0)
10938 int end = 4 + (op & 0x07);
10939 bool first = true;
10940 int i;
10942 printf (" pop {");
10943 for (i = 4; i <= end; i++)
10945 if (first)
10946 first = false;
10947 else
10948 printf (", ");
10949 printf ("r%d", i);
10951 if (op & 0x08)
10953 if (!first)
10954 printf (", ");
10955 printf ("r14");
10957 printf ("}");
10959 else if (op == 0xb0)
10960 printf (_(" finish"));
10961 else if (op == 0xb1)
10963 GET_OP (op2);
10964 if (op2 == 0 || (op2 & 0xf0) != 0)
10965 printf (_("[Spare]"));
10966 else
10968 unsigned int mask = op2 & 0x0f;
10969 bool first = true;
10970 int i;
10972 printf ("pop {");
10973 for (i = 0; i < 12; i++)
10974 if (mask & (1 << i))
10976 if (first)
10977 first = false;
10978 else
10979 printf (", ");
10980 printf ("r%d", i);
10982 printf ("}");
10985 else if (op == 0xb2)
10987 unsigned char buf[9];
10988 unsigned int i, len;
10989 uint64_t offset;
10991 for (i = 0; i < sizeof (buf); i++)
10993 GET_OP (buf[i]);
10994 if ((buf[i] & 0x80) == 0)
10995 break;
10997 if (i == sizeof (buf))
10999 error (_("corrupt change to vsp\n"));
11000 res = false;
11002 else
11004 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
11005 assert (len == i + 1);
11006 offset = offset * 4 + 0x204;
11007 printf ("vsp = vsp + %" PRId64, offset);
11010 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
11012 unsigned int first, last;
11014 GET_OP (op2);
11015 first = op2 >> 4;
11016 last = op2 & 0x0f;
11017 if (op == 0xc8)
11018 first = first + 16;
11019 printf ("pop {D%d", first);
11020 if (last)
11021 printf ("-D%d", first + last);
11022 printf ("}");
11024 else if (op == 0xb4)
11025 printf (_(" pop {ra_auth_code}"));
11026 else if (op == 0xb5)
11027 printf (_(" vsp as modifier for PAC validation"));
11028 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
11030 unsigned int count = op & 0x07;
11032 printf ("pop {D8");
11033 if (count)
11034 printf ("-D%d", 8 + count);
11035 printf ("}");
11037 else if (op >= 0xc0 && op <= 0xc5)
11039 unsigned int count = op & 0x07;
11041 printf (" pop {wR10");
11042 if (count)
11043 printf ("-wR%d", 10 + count);
11044 printf ("}");
11046 else if (op == 0xc6)
11048 unsigned int first, last;
11050 GET_OP (op2);
11051 first = op2 >> 4;
11052 last = op2 & 0x0f;
11053 printf ("pop {wR%d", first);
11054 if (last)
11055 printf ("-wR%d", first + last);
11056 printf ("}");
11058 else if (op == 0xc7)
11060 GET_OP (op2);
11061 if (op2 == 0 || (op2 & 0xf0) != 0)
11062 printf (_("[Spare]"));
11063 else
11065 unsigned int mask = op2 & 0x0f;
11066 bool first = true;
11067 int i;
11069 printf ("pop {");
11070 for (i = 0; i < 4; i++)
11071 if (mask & (1 << i))
11073 if (first)
11074 first = false;
11075 else
11076 printf (", ");
11077 printf ("wCGR%d", i);
11079 printf ("}");
11082 else
11084 printf (_(" [unsupported opcode]"));
11085 res = false;
11088 printf ("\n");
11091 return res;
11094 static bool
11095 decode_tic6x_unwind_bytecode (Filedata * filedata,
11096 struct arm_unw_aux_info * aux,
11097 unsigned int word,
11098 unsigned int remaining,
11099 unsigned int more_words,
11100 uint64_t data_offset,
11101 Elf_Internal_Shdr * data_sec,
11102 struct arm_section * data_arm_sec)
11104 struct absaddr addr;
11106 /* Decode the unwinding instructions. */
11107 while (1)
11109 unsigned int op, op2;
11111 ADVANCE;
11112 if (remaining == 0)
11113 break;
11114 remaining--;
11115 op = word >> 24;
11116 word <<= 8;
11118 printf (" 0x%02x ", op);
11120 if ((op & 0xc0) == 0x00)
11122 int offset = ((op & 0x3f) << 3) + 8;
11123 printf (" sp = sp + %d", offset);
11125 else if ((op & 0xc0) == 0x80)
11127 GET_OP (op2);
11128 if (op == 0x80 && op2 == 0)
11129 printf (_("Refuse to unwind"));
11130 else
11132 unsigned int mask = ((op & 0x1f) << 8) | op2;
11133 if (op & 0x20)
11134 printf ("pop compact {");
11135 else
11136 printf ("pop {");
11138 decode_tic6x_unwind_regmask (mask);
11139 printf("}");
11142 else if ((op & 0xf0) == 0xc0)
11144 unsigned int reg;
11145 unsigned int nregs;
11146 unsigned int i;
11147 const char *name;
11148 struct
11150 unsigned int offset;
11151 unsigned int reg;
11152 } regpos[16];
11154 /* Scan entire instruction first so that GET_OP output is not
11155 interleaved with disassembly. */
11156 nregs = 0;
11157 for (i = 0; nregs < (op & 0xf); i++)
11159 GET_OP (op2);
11160 reg = op2 >> 4;
11161 if (reg != 0xf)
11163 regpos[nregs].offset = i * 2;
11164 regpos[nregs].reg = reg;
11165 nregs++;
11168 reg = op2 & 0xf;
11169 if (reg != 0xf)
11171 regpos[nregs].offset = i * 2 + 1;
11172 regpos[nregs].reg = reg;
11173 nregs++;
11177 printf (_("pop frame {"));
11178 if (nregs == 0)
11180 printf (_("*corrupt* - no registers specified"));
11182 else
11184 reg = nregs - 1;
11185 for (i = i * 2; i > 0; i--)
11187 if (regpos[reg].offset == i - 1)
11189 name = tic6x_unwind_regnames[regpos[reg].reg];
11190 if (reg > 0)
11191 reg--;
11193 else
11194 name = _("[pad]");
11196 fputs (name, stdout);
11197 if (i > 1)
11198 printf (", ");
11202 printf ("}");
11204 else if (op == 0xd0)
11205 printf (" MOV FP, SP");
11206 else if (op == 0xd1)
11207 printf (" __c6xabi_pop_rts");
11208 else if (op == 0xd2)
11210 unsigned char buf[9];
11211 unsigned int i, len;
11212 uint64_t offset;
11214 for (i = 0; i < sizeof (buf); i++)
11216 GET_OP (buf[i]);
11217 if ((buf[i] & 0x80) == 0)
11218 break;
11220 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
11221 if (i == sizeof (buf))
11223 warn (_("Corrupt stack pointer adjustment detected\n"));
11224 return false;
11227 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
11228 assert (len == i + 1);
11229 offset = offset * 8 + 0x408;
11230 printf (_("sp = sp + %" PRId64), offset);
11232 else if ((op & 0xf0) == 0xe0)
11234 if ((op & 0x0f) == 7)
11235 printf (" RETURN");
11236 else
11237 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
11239 else
11241 printf (_(" [unsupported opcode]"));
11243 putchar ('\n');
11246 return true;
11249 static uint64_t
11250 arm_expand_prel31 (Filedata * filedata, uint64_t word, uint64_t where)
11252 uint64_t offset;
11254 offset = word & 0x7fffffff;
11255 if (offset & 0x40000000)
11256 offset |= ~ (uint64_t) 0x7fffffff;
11258 if (filedata->file_header.e_machine == EM_TI_C6000)
11259 offset <<= 1;
11261 return offset + where;
11264 static bool
11265 decode_arm_unwind (Filedata * filedata,
11266 struct arm_unw_aux_info * aux,
11267 unsigned int word,
11268 unsigned int remaining,
11269 uint64_t data_offset,
11270 Elf_Internal_Shdr * data_sec,
11271 struct arm_section * data_arm_sec)
11273 int per_index;
11274 unsigned int more_words = 0;
11275 struct absaddr addr;
11276 uint64_t sym_name = (uint64_t) -1;
11277 bool res = true;
11279 if (remaining == 0)
11281 /* Fetch the first word.
11282 Note - when decoding an object file the address extracted
11283 here will always be 0. So we also pass in the sym_name
11284 parameter so that we can find the symbol associated with
11285 the personality routine. */
11286 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
11287 & word, & addr, & sym_name))
11288 return false;
11290 remaining = 4;
11292 else
11294 addr.section = SHN_UNDEF;
11295 addr.offset = 0;
11298 if ((word & 0x80000000) == 0)
11300 /* Expand prel31 for personality routine. */
11301 uint64_t fn;
11302 const char *procname;
11304 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
11305 printf (_(" Personality routine: "));
11306 if (fn == 0
11307 && addr.section == SHN_UNDEF && addr.offset == 0
11308 && sym_name != (uint64_t) -1 && sym_name < aux->strtab_size)
11310 procname = aux->strtab + sym_name;
11311 print_vma (fn, PREFIX_HEX);
11312 if (procname)
11314 fputs (" <", stdout);
11315 fputs (procname, stdout);
11316 fputc ('>', stdout);
11319 else
11320 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
11321 fputc ('\n', stdout);
11323 /* The GCC personality routines use the standard compact
11324 encoding, starting with one byte giving the number of
11325 words. */
11326 if (procname != NULL
11327 && (startswith (procname, "__gcc_personality_v0")
11328 || startswith (procname, "__gxx_personality_v0")
11329 || startswith (procname, "__gcj_personality_v0")
11330 || startswith (procname, "__gnu_objc_personality_v0")))
11332 remaining = 0;
11333 more_words = 1;
11334 ADVANCE;
11335 if (!remaining)
11337 printf (_(" [Truncated data]\n"));
11338 return false;
11340 more_words = word >> 24;
11341 word <<= 8;
11342 remaining--;
11343 per_index = -1;
11345 else
11346 return true;
11348 else
11350 /* ARM EHABI Section 6.3:
11352 An exception-handling table entry for the compact model looks like:
11354 31 30-28 27-24 23-0
11355 -- ----- ----- ----
11356 1 0 index Data for personalityRoutine[index] */
11358 if (filedata->file_header.e_machine == EM_ARM
11359 && (word & 0x70000000))
11361 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
11362 res = false;
11365 per_index = (word >> 24) & 0x7f;
11366 printf (_(" Compact model index: %d\n"), per_index);
11367 if (per_index == 0)
11369 more_words = 0;
11370 word <<= 8;
11371 remaining--;
11373 else if (per_index < 3)
11375 more_words = (word >> 16) & 0xff;
11376 word <<= 16;
11377 remaining -= 2;
11381 switch (filedata->file_header.e_machine)
11383 case EM_ARM:
11384 if (per_index < 3)
11386 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
11387 data_offset, data_sec, data_arm_sec))
11388 res = false;
11390 else
11392 warn (_("Unknown ARM compact model index encountered\n"));
11393 printf (_(" [reserved]\n"));
11394 res = false;
11396 break;
11398 case EM_TI_C6000:
11399 if (per_index < 3)
11401 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
11402 data_offset, data_sec, data_arm_sec))
11403 res = false;
11405 else if (per_index < 5)
11407 if (((word >> 17) & 0x7f) == 0x7f)
11408 printf (_(" Restore stack from frame pointer\n"));
11409 else
11410 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
11411 printf (_(" Registers restored: "));
11412 if (per_index == 4)
11413 printf (" (compact) ");
11414 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
11415 putchar ('\n');
11416 printf (_(" Return register: %s\n"),
11417 tic6x_unwind_regnames[word & 0xf]);
11419 else
11420 printf (_(" [reserved (%d)]\n"), per_index);
11421 break;
11423 default:
11424 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
11425 filedata->file_header.e_machine);
11426 res = false;
11429 /* Decode the descriptors. Not implemented. */
11431 return res;
11434 static bool
11435 dump_arm_unwind (Filedata * filedata,
11436 struct arm_unw_aux_info * aux,
11437 Elf_Internal_Shdr * exidx_sec)
11439 struct arm_section exidx_arm_sec, extab_arm_sec;
11440 unsigned int i, exidx_len;
11441 uint64_t j, nfuns;
11442 bool res = true;
11444 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
11445 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
11446 exidx_len = exidx_sec->sh_size / 8;
11448 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
11449 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
11450 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
11451 aux->funtab[nfuns++] = aux->symtab[j];
11452 aux->nfuns = nfuns;
11453 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
11455 for (i = 0; i < exidx_len; i++)
11457 unsigned int exidx_fn, exidx_entry;
11458 struct absaddr fn_addr, entry_addr;
11459 uint64_t fn;
11461 fputc ('\n', stdout);
11463 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
11464 8 * i, & exidx_fn, & fn_addr, NULL)
11465 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
11466 8 * i + 4, & exidx_entry, & entry_addr, NULL))
11468 free (aux->funtab);
11469 arm_free_section (& exidx_arm_sec);
11470 arm_free_section (& extab_arm_sec);
11471 return false;
11474 /* ARM EHABI, Section 5:
11475 An index table entry consists of 2 words.
11476 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
11477 if (exidx_fn & 0x80000000)
11479 warn (_("corrupt index table entry: %x\n"), exidx_fn);
11480 res = false;
11483 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
11485 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
11486 fputs (": ", stdout);
11488 if (exidx_entry == 1)
11490 print_vma (exidx_entry, PREFIX_HEX);
11491 fputs (" [cantunwind]\n", stdout);
11493 else if (exidx_entry & 0x80000000)
11495 print_vma (exidx_entry, PREFIX_HEX);
11496 fputc ('\n', stdout);
11497 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
11499 else
11501 uint64_t table, table_offset = 0;
11502 Elf_Internal_Shdr *table_sec;
11504 fputs ("@", stdout);
11505 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
11506 print_vma (table, PREFIX_HEX);
11507 printf ("\n");
11509 /* Locate the matching .ARM.extab. */
11510 if (entry_addr.section != SHN_UNDEF
11511 && entry_addr.section < filedata->file_header.e_shnum)
11513 table_sec = filedata->section_headers + entry_addr.section;
11514 table_offset = entry_addr.offset;
11515 /* PR 18879 */
11516 if (table_offset > table_sec->sh_size)
11518 warn (_("Unwind entry contains corrupt offset (%#" PRIx64 ") into section %s\n"),
11519 table_offset,
11520 printable_section_name (filedata, table_sec));
11521 res = false;
11522 continue;
11525 else
11527 table_sec = find_section_by_address (filedata, table);
11528 if (table_sec != NULL)
11529 table_offset = table - table_sec->sh_addr;
11532 if (table_sec == NULL)
11534 warn (_("Could not locate .ARM.extab section containing %#" PRIx64 ".\n"),
11535 table);
11536 res = false;
11537 continue;
11540 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
11541 &extab_arm_sec))
11542 res = false;
11546 printf ("\n");
11548 free (aux->funtab);
11549 arm_free_section (&exidx_arm_sec);
11550 arm_free_section (&extab_arm_sec);
11552 return res;
11555 /* Used for both ARM and C6X unwinding tables. */
11557 static bool
11558 arm_process_unwind (Filedata * filedata)
11560 struct arm_unw_aux_info aux;
11561 Elf_Internal_Shdr *unwsec = NULL;
11562 Elf_Internal_Shdr *sec;
11563 size_t i;
11564 unsigned int sec_type;
11565 bool res = true;
11567 switch (filedata->file_header.e_machine)
11569 case EM_ARM:
11570 sec_type = SHT_ARM_EXIDX;
11571 break;
11573 case EM_TI_C6000:
11574 sec_type = SHT_C6000_UNWIND;
11575 break;
11577 default:
11578 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
11579 filedata->file_header.e_machine);
11580 return false;
11583 if (filedata->string_table == NULL)
11584 return false;
11586 memset (& aux, 0, sizeof (aux));
11587 aux.filedata = filedata;
11589 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
11591 if (sec->sh_type == SHT_SYMTAB)
11593 if (aux.symtab)
11595 error (_("Multiple symbol tables encountered\n"));
11596 free (aux.symtab);
11597 aux.symtab = NULL;
11598 free (aux.strtab);
11599 aux.strtab = NULL;
11601 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
11602 &aux.strtab, &aux.strtab_size))
11603 return false;
11605 else if (sec->sh_type == sec_type)
11606 unwsec = sec;
11609 if (unwsec == NULL)
11610 printf (_("\nThere are no unwind sections in this file.\n"));
11611 else
11612 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
11614 if (sec->sh_type == sec_type)
11616 uint64_t num_unwind = sec->sh_size / (2 * eh_addr_size);
11617 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
11618 "contains %" PRIu64 " entry:\n",
11619 "\nUnwind section '%s' at offset %#" PRIx64 " "
11620 "contains %" PRIu64 " entries:\n",
11621 num_unwind),
11622 printable_section_name (filedata, sec),
11623 sec->sh_offset,
11624 num_unwind);
11626 if (! dump_arm_unwind (filedata, &aux, sec))
11627 res = false;
11631 free (aux.symtab);
11632 free ((char *) aux.strtab);
11634 return res;
11637 static bool
11638 no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
11640 printf (_("No processor specific unwind information to decode\n"));
11641 return true;
11644 static bool
11645 process_unwind (Filedata * filedata)
11647 struct unwind_handler
11649 unsigned int machtype;
11650 bool (* handler)(Filedata *);
11651 } handlers[] =
11653 { EM_ARM, arm_process_unwind },
11654 { EM_IA_64, ia64_process_unwind },
11655 { EM_PARISC, hppa_process_unwind },
11656 { EM_TI_C6000, arm_process_unwind },
11657 { EM_386, no_processor_specific_unwind },
11658 { EM_X86_64, no_processor_specific_unwind },
11659 { 0, NULL }
11661 int i;
11663 if (!do_unwind)
11664 return true;
11666 for (i = 0; handlers[i].handler != NULL; i++)
11667 if (filedata->file_header.e_machine == handlers[i].machtype)
11668 return handlers[i].handler (filedata);
11670 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
11671 get_machine_name (filedata->file_header.e_machine));
11672 return true;
11675 static void
11676 dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
11678 switch (entry->d_tag)
11680 case DT_AARCH64_BTI_PLT:
11681 case DT_AARCH64_PAC_PLT:
11682 break;
11683 default:
11684 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11685 break;
11687 putchar ('\n');
11690 static void
11691 dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
11693 switch (entry->d_tag)
11695 case DT_MIPS_FLAGS:
11696 if (entry->d_un.d_val == 0)
11697 printf (_("NONE"));
11698 else
11700 static const char * opts[] =
11702 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
11703 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
11704 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
11705 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
11706 "RLD_ORDER_SAFE"
11708 unsigned int cnt;
11709 bool first = true;
11711 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
11712 if (entry->d_un.d_val & (1 << cnt))
11714 printf ("%s%s", first ? "" : " ", opts[cnt]);
11715 first = false;
11718 break;
11720 case DT_MIPS_IVERSION:
11721 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11722 printf (_("Interface Version: %s"),
11723 get_dynamic_name (filedata, entry->d_un.d_val));
11724 else
11725 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
11726 entry->d_un.d_ptr);
11727 break;
11729 case DT_MIPS_TIME_STAMP:
11731 char timebuf[128];
11732 struct tm * tmp;
11733 time_t atime = entry->d_un.d_val;
11735 tmp = gmtime (&atime);
11736 /* PR 17531: file: 6accc532. */
11737 if (tmp == NULL)
11738 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
11739 else
11740 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
11741 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11742 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
11743 printf (_("Time Stamp: %s"), timebuf);
11745 break;
11747 case DT_MIPS_RLD_VERSION:
11748 case DT_MIPS_LOCAL_GOTNO:
11749 case DT_MIPS_CONFLICTNO:
11750 case DT_MIPS_LIBLISTNO:
11751 case DT_MIPS_SYMTABNO:
11752 case DT_MIPS_UNREFEXTNO:
11753 case DT_MIPS_HIPAGENO:
11754 case DT_MIPS_DELTA_CLASS_NO:
11755 case DT_MIPS_DELTA_INSTANCE_NO:
11756 case DT_MIPS_DELTA_RELOC_NO:
11757 case DT_MIPS_DELTA_SYM_NO:
11758 case DT_MIPS_DELTA_CLASSSYM_NO:
11759 case DT_MIPS_COMPACT_SIZE:
11760 print_vma (entry->d_un.d_val, DEC);
11761 break;
11763 case DT_MIPS_XHASH:
11764 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11765 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
11766 /* Falls through. */
11768 default:
11769 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11771 putchar ('\n');
11774 static void
11775 dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
11777 switch (entry->d_tag)
11779 case DT_HP_DLD_FLAGS:
11781 static struct
11783 unsigned int bit;
11784 const char * str;
11786 flags[] =
11788 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
11789 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
11790 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
11791 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
11792 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
11793 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
11794 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
11795 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
11796 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
11797 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
11798 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
11799 { DT_HP_GST, "HP_GST" },
11800 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
11801 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
11802 { DT_HP_NODELETE, "HP_NODELETE" },
11803 { DT_HP_GROUP, "HP_GROUP" },
11804 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
11806 bool first = true;
11807 size_t cnt;
11808 uint64_t val = entry->d_un.d_val;
11810 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
11811 if (val & flags[cnt].bit)
11813 if (! first)
11814 putchar (' ');
11815 fputs (flags[cnt].str, stdout);
11816 first = false;
11817 val ^= flags[cnt].bit;
11820 if (val != 0 || first)
11822 if (! first)
11823 putchar (' ');
11824 print_vma (val, HEX);
11827 break;
11829 default:
11830 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11831 break;
11833 putchar ('\n');
11836 /* VMS vs Unix time offset and factor. */
11838 #define VMS_EPOCH_OFFSET 35067168000000000LL
11839 #define VMS_GRANULARITY_FACTOR 10000000
11840 #ifndef INT64_MIN
11841 #define INT64_MIN (-9223372036854775807LL - 1)
11842 #endif
11844 /* Display a VMS time in a human readable format. */
11846 static void
11847 print_vms_time (int64_t vmstime)
11849 struct tm *tm = NULL;
11850 time_t unxtime;
11852 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
11854 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
11855 unxtime = vmstime;
11856 if (unxtime == vmstime)
11857 tm = gmtime (&unxtime);
11859 if (tm != NULL)
11860 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
11861 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
11862 tm->tm_hour, tm->tm_min, tm->tm_sec);
11865 static void
11866 dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
11868 switch (entry->d_tag)
11870 case DT_IA_64_PLT_RESERVE:
11871 /* First 3 slots reserved. */
11872 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11873 printf (" -- ");
11874 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
11875 break;
11877 case DT_IA_64_VMS_LINKTIME:
11878 print_vms_time (entry->d_un.d_val);
11879 break;
11881 case DT_IA_64_VMS_LNKFLAGS:
11882 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11883 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
11884 printf (" CALL_DEBUG");
11885 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
11886 printf (" NOP0BUFS");
11887 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
11888 printf (" P0IMAGE");
11889 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
11890 printf (" MKTHREADS");
11891 if (entry->d_un.d_val & VMS_LF_UPCALLS)
11892 printf (" UPCALLS");
11893 if (entry->d_un.d_val & VMS_LF_IMGSTA)
11894 printf (" IMGSTA");
11895 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
11896 printf (" INITIALIZE");
11897 if (entry->d_un.d_val & VMS_LF_MAIN)
11898 printf (" MAIN");
11899 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
11900 printf (" EXE_INIT");
11901 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
11902 printf (" TBK_IN_IMG");
11903 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
11904 printf (" DBG_IN_IMG");
11905 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
11906 printf (" TBK_IN_DSF");
11907 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
11908 printf (" DBG_IN_DSF");
11909 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
11910 printf (" SIGNATURES");
11911 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
11912 printf (" REL_SEG_OFF");
11913 break;
11915 default:
11916 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11917 break;
11919 putchar ('\n');
11922 static bool
11923 get_32bit_dynamic_section (Filedata * filedata)
11925 Elf32_External_Dyn * edyn;
11926 Elf32_External_Dyn * ext;
11927 Elf_Internal_Dyn * entry;
11929 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
11930 filedata->dynamic_addr, 1,
11931 filedata->dynamic_size,
11932 _("dynamic section"));
11933 if (!edyn)
11934 return false;
11936 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11937 might not have the luxury of section headers. Look for the DT_NULL
11938 terminator to determine the number of entries. */
11939 for (ext = edyn, filedata->dynamic_nent = 0;
11940 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
11941 ext++)
11943 filedata->dynamic_nent++;
11944 if (BYTE_GET (ext->d_tag) == DT_NULL)
11945 break;
11948 filedata->dynamic_section
11949 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11950 if (filedata->dynamic_section == NULL)
11952 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11953 filedata->dynamic_nent);
11954 free (edyn);
11955 return false;
11958 for (ext = edyn, entry = filedata->dynamic_section;
11959 entry < filedata->dynamic_section + filedata->dynamic_nent;
11960 ext++, entry++)
11962 entry->d_tag = BYTE_GET (ext->d_tag);
11963 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
11966 free (edyn);
11968 return true;
11971 static bool
11972 get_64bit_dynamic_section (Filedata * filedata)
11974 Elf64_External_Dyn * edyn;
11975 Elf64_External_Dyn * ext;
11976 Elf_Internal_Dyn * entry;
11978 /* Read in the data. */
11979 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
11980 filedata->dynamic_addr, 1,
11981 filedata->dynamic_size,
11982 _("dynamic section"));
11983 if (!edyn)
11984 return false;
11986 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11987 might not have the luxury of section headers. Look for the DT_NULL
11988 terminator to determine the number of entries. */
11989 for (ext = edyn, filedata->dynamic_nent = 0;
11990 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
11991 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
11992 ext++)
11994 filedata->dynamic_nent++;
11995 if (BYTE_GET (ext->d_tag) == DT_NULL)
11996 break;
11999 filedata->dynamic_section
12000 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
12001 if (filedata->dynamic_section == NULL)
12003 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
12004 filedata->dynamic_nent);
12005 free (edyn);
12006 return false;
12009 /* Convert from external to internal formats. */
12010 for (ext = edyn, entry = filedata->dynamic_section;
12011 entry < filedata->dynamic_section + filedata->dynamic_nent;
12012 ext++, entry++)
12014 entry->d_tag = BYTE_GET (ext->d_tag);
12015 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
12018 free (edyn);
12020 return true;
12023 static bool
12024 get_dynamic_section (Filedata *filedata)
12026 if (filedata->dynamic_section)
12027 return true;
12029 if (is_32bit_elf)
12030 return get_32bit_dynamic_section (filedata);
12031 else
12032 return get_64bit_dynamic_section (filedata);
12035 static void
12036 print_dynamic_flags (uint64_t flags)
12038 bool first = true;
12040 while (flags)
12042 uint64_t flag;
12044 flag = flags & - flags;
12045 flags &= ~ flag;
12047 if (first)
12048 first = false;
12049 else
12050 putc (' ', stdout);
12052 switch (flag)
12054 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
12055 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
12056 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
12057 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
12058 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
12059 default: fputs (_("unknown"), stdout); break;
12062 puts ("");
12065 static uint64_t *
12066 get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
12068 unsigned char * e_data;
12069 uint64_t * i_data;
12071 /* If size_t is smaller than uint64_t, eg because you are building
12072 on a 32-bit host, then make sure that when number is cast to
12073 size_t no information is lost. */
12074 if ((size_t) number != number
12075 || ent_size * number / ent_size != number)
12077 error (_("Size overflow prevents reading %" PRIu64
12078 " elements of size %u\n"),
12079 number, ent_size);
12080 return NULL;
12083 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
12084 attempting to allocate memory when the read is bound to fail. */
12085 if (ent_size * number > filedata->file_size)
12087 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
12088 number);
12089 return NULL;
12092 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
12093 if (e_data == NULL)
12095 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
12096 number);
12097 return NULL;
12100 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
12102 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
12103 number * ent_size);
12104 free (e_data);
12105 return NULL;
12108 i_data = (uint64_t *) cmalloc ((size_t) number, sizeof (*i_data));
12109 if (i_data == NULL)
12111 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
12112 number);
12113 free (e_data);
12114 return NULL;
12117 while (number--)
12118 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
12120 free (e_data);
12122 return i_data;
12125 static uint64_t
12126 get_num_dynamic_syms (Filedata * filedata)
12128 uint64_t num_of_syms = 0;
12130 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
12131 return num_of_syms;
12133 if (filedata->dynamic_info[DT_HASH])
12135 unsigned char nb[8];
12136 unsigned char nc[8];
12137 unsigned int hash_ent_size = 4;
12139 if ((filedata->file_header.e_machine == EM_ALPHA
12140 || filedata->file_header.e_machine == EM_S390
12141 || filedata->file_header.e_machine == EM_S390_OLD)
12142 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
12143 hash_ent_size = 8;
12145 if (fseek64 (filedata->handle,
12146 (filedata->archive_file_offset
12147 + offset_from_vma (filedata,
12148 filedata->dynamic_info[DT_HASH],
12149 sizeof nb + sizeof nc)),
12150 SEEK_SET))
12152 error (_("Unable to seek to start of dynamic information\n"));
12153 goto no_hash;
12156 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
12158 error (_("Failed to read in number of buckets\n"));
12159 goto no_hash;
12162 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
12164 error (_("Failed to read in number of chains\n"));
12165 goto no_hash;
12168 filedata->nbuckets = byte_get (nb, hash_ent_size);
12169 filedata->nchains = byte_get (nc, hash_ent_size);
12171 if (filedata->nbuckets != 0 && filedata->nchains != 0)
12173 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
12174 hash_ent_size);
12175 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
12176 hash_ent_size);
12178 if (filedata->buckets != NULL && filedata->chains != NULL)
12179 num_of_syms = filedata->nchains;
12181 no_hash:
12182 if (num_of_syms == 0)
12184 free (filedata->buckets);
12185 filedata->buckets = NULL;
12186 free (filedata->chains);
12187 filedata->chains = NULL;
12188 filedata->nbuckets = 0;
12192 if (filedata->dynamic_info_DT_GNU_HASH)
12194 unsigned char nb[16];
12195 uint64_t i, maxchain = 0xffffffff, bitmaskwords;
12196 uint64_t buckets_vma;
12197 uint64_t hn;
12199 if (fseek64 (filedata->handle,
12200 (filedata->archive_file_offset
12201 + offset_from_vma (filedata,
12202 filedata->dynamic_info_DT_GNU_HASH,
12203 sizeof nb)),
12204 SEEK_SET))
12206 error (_("Unable to seek to start of dynamic information\n"));
12207 goto no_gnu_hash;
12210 if (fread (nb, 16, 1, filedata->handle) != 1)
12212 error (_("Failed to read in number of buckets\n"));
12213 goto no_gnu_hash;
12216 filedata->ngnubuckets = byte_get (nb, 4);
12217 filedata->gnusymidx = byte_get (nb + 4, 4);
12218 bitmaskwords = byte_get (nb + 8, 4);
12219 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
12220 if (is_32bit_elf)
12221 buckets_vma += bitmaskwords * 4;
12222 else
12223 buckets_vma += bitmaskwords * 8;
12225 if (fseek64 (filedata->handle,
12226 (filedata->archive_file_offset
12227 + offset_from_vma (filedata, buckets_vma, 4)),
12228 SEEK_SET))
12230 error (_("Unable to seek to start of dynamic information\n"));
12231 goto no_gnu_hash;
12234 filedata->gnubuckets
12235 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
12237 if (filedata->gnubuckets == NULL)
12238 goto no_gnu_hash;
12240 for (i = 0; i < filedata->ngnubuckets; i++)
12241 if (filedata->gnubuckets[i] != 0)
12243 if (filedata->gnubuckets[i] < filedata->gnusymidx)
12244 goto no_gnu_hash;
12246 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
12247 maxchain = filedata->gnubuckets[i];
12250 if (maxchain == 0xffffffff)
12251 goto no_gnu_hash;
12253 maxchain -= filedata->gnusymidx;
12255 if (fseek64 (filedata->handle,
12256 (filedata->archive_file_offset
12257 + offset_from_vma (filedata,
12258 buckets_vma + 4 * (filedata->ngnubuckets
12259 + maxchain),
12260 4)),
12261 SEEK_SET))
12263 error (_("Unable to seek to start of dynamic information\n"));
12264 goto no_gnu_hash;
12269 if (fread (nb, 4, 1, filedata->handle) != 1)
12271 error (_("Failed to determine last chain length\n"));
12272 goto no_gnu_hash;
12275 if (maxchain + 1 == 0)
12276 goto no_gnu_hash;
12278 ++maxchain;
12280 while ((byte_get (nb, 4) & 1) == 0);
12282 if (fseek64 (filedata->handle,
12283 (filedata->archive_file_offset
12284 + offset_from_vma (filedata, (buckets_vma
12285 + 4 * filedata->ngnubuckets),
12286 4)),
12287 SEEK_SET))
12289 error (_("Unable to seek to start of dynamic information\n"));
12290 goto no_gnu_hash;
12293 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
12294 filedata->ngnuchains = maxchain;
12296 if (filedata->gnuchains == NULL)
12297 goto no_gnu_hash;
12299 if (filedata->dynamic_info_DT_MIPS_XHASH)
12301 if (fseek64 (filedata->handle,
12302 (filedata->archive_file_offset
12303 + offset_from_vma (filedata, (buckets_vma
12304 + 4 * (filedata->ngnubuckets
12305 + maxchain)), 4)),
12306 SEEK_SET))
12308 error (_("Unable to seek to start of dynamic information\n"));
12309 goto no_gnu_hash;
12312 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
12313 if (filedata->mipsxlat == NULL)
12314 goto no_gnu_hash;
12317 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
12318 if (filedata->gnubuckets[hn] != 0)
12320 uint64_t si = filedata->gnubuckets[hn];
12321 uint64_t off = si - filedata->gnusymidx;
12325 if (filedata->dynamic_info_DT_MIPS_XHASH)
12327 if (off < filedata->ngnuchains
12328 && filedata->mipsxlat[off] >= num_of_syms)
12329 num_of_syms = filedata->mipsxlat[off] + 1;
12331 else
12333 if (si >= num_of_syms)
12334 num_of_syms = si + 1;
12336 si++;
12338 while (off < filedata->ngnuchains
12339 && (filedata->gnuchains[off++] & 1) == 0);
12342 if (num_of_syms == 0)
12344 no_gnu_hash:
12345 free (filedata->mipsxlat);
12346 filedata->mipsxlat = NULL;
12347 free (filedata->gnuchains);
12348 filedata->gnuchains = NULL;
12349 free (filedata->gnubuckets);
12350 filedata->gnubuckets = NULL;
12351 filedata->ngnubuckets = 0;
12352 filedata->ngnuchains = 0;
12356 return num_of_syms;
12359 /* Parse and display the contents of the dynamic section. */
12361 static bool
12362 process_dynamic_section (Filedata * filedata)
12364 Elf_Internal_Dyn * entry;
12366 if (filedata->dynamic_size <= 1)
12368 if (do_dynamic)
12370 if (filedata->is_separate)
12371 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
12372 printable_string (filedata->file_name, 0));
12373 else
12374 printf (_("\nThere is no dynamic section in this file.\n"));
12377 return true;
12380 if (!get_dynamic_section (filedata))
12381 return false;
12383 /* Find the appropriate symbol table. */
12384 if (filedata->dynamic_symbols == NULL || do_histogram)
12386 uint64_t num_of_syms;
12388 for (entry = filedata->dynamic_section;
12389 entry < filedata->dynamic_section + filedata->dynamic_nent;
12390 ++entry)
12391 if (entry->d_tag == DT_SYMTAB)
12392 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
12393 else if (entry->d_tag == DT_SYMENT)
12394 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
12395 else if (entry->d_tag == DT_HASH)
12396 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
12397 else if (entry->d_tag == DT_GNU_HASH)
12398 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
12399 else if ((filedata->file_header.e_machine == EM_MIPS
12400 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
12401 && entry->d_tag == DT_MIPS_XHASH)
12403 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
12404 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
12407 num_of_syms = get_num_dynamic_syms (filedata);
12409 if (num_of_syms != 0
12410 && filedata->dynamic_symbols == NULL
12411 && filedata->dynamic_info[DT_SYMTAB]
12412 && filedata->dynamic_info[DT_SYMENT])
12414 Elf_Internal_Phdr *seg;
12415 uint64_t vma = filedata->dynamic_info[DT_SYMTAB];
12417 if (! get_program_headers (filedata))
12419 error (_("Cannot interpret virtual addresses "
12420 "without program headers.\n"));
12421 return false;
12424 for (seg = filedata->program_headers;
12425 seg < filedata->program_headers + filedata->file_header.e_phnum;
12426 ++seg)
12428 if (seg->p_type != PT_LOAD)
12429 continue;
12431 if (seg->p_offset + seg->p_filesz > filedata->file_size)
12433 /* See PR 21379 for a reproducer. */
12434 error (_("Invalid PT_LOAD entry\n"));
12435 return false;
12438 if (vma >= (seg->p_vaddr & -seg->p_align)
12439 && vma < seg->p_vaddr + seg->p_filesz)
12441 /* Since we do not know how big the symbol table is,
12442 we default to reading in up to the end of PT_LOAD
12443 segment and processing that. This is overkill, I
12444 know, but it should work. */
12445 Elf_Internal_Shdr section;
12446 section.sh_offset = (vma - seg->p_vaddr
12447 + seg->p_offset);
12448 section.sh_size = (num_of_syms
12449 * filedata->dynamic_info[DT_SYMENT]);
12450 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
12452 if (do_checks
12453 && filedata->dynamic_symtab_section != NULL
12454 && ((filedata->dynamic_symtab_section->sh_offset
12455 != section.sh_offset)
12456 || (filedata->dynamic_symtab_section->sh_size
12457 != section.sh_size)
12458 || (filedata->dynamic_symtab_section->sh_entsize
12459 != section.sh_entsize)))
12460 warn (_("\
12461 the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
12463 section.sh_name = filedata->string_table_length;
12464 filedata->dynamic_symbols
12465 = get_elf_symbols (filedata, &section,
12466 &filedata->num_dynamic_syms);
12467 if (filedata->dynamic_symbols == NULL
12468 || filedata->num_dynamic_syms != num_of_syms)
12470 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
12471 return false;
12473 break;
12479 /* Similarly find a string table. */
12480 if (filedata->dynamic_strings == NULL)
12481 for (entry = filedata->dynamic_section;
12482 entry < filedata->dynamic_section + filedata->dynamic_nent;
12483 ++entry)
12485 if (entry->d_tag == DT_STRTAB)
12486 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
12488 if (entry->d_tag == DT_STRSZ)
12489 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
12491 if (filedata->dynamic_info[DT_STRTAB]
12492 && filedata->dynamic_info[DT_STRSZ])
12494 uint64_t offset;
12495 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
12497 offset = offset_from_vma (filedata,
12498 filedata->dynamic_info[DT_STRTAB],
12499 str_tab_len);
12500 if (do_checks
12501 && filedata->dynamic_strtab_section
12502 && ((filedata->dynamic_strtab_section->sh_offset
12503 != (file_ptr) offset)
12504 || (filedata->dynamic_strtab_section->sh_size
12505 != str_tab_len)))
12506 warn (_("\
12507 the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
12509 filedata->dynamic_strings
12510 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
12511 _("dynamic string table"));
12512 if (filedata->dynamic_strings == NULL)
12514 error (_("Corrupt DT_STRTAB dynamic entry\n"));
12515 break;
12518 filedata->dynamic_strings_length = str_tab_len;
12519 break;
12523 /* And find the syminfo section if available. */
12524 if (filedata->dynamic_syminfo == NULL)
12526 uint64_t syminsz = 0;
12528 for (entry = filedata->dynamic_section;
12529 entry < filedata->dynamic_section + filedata->dynamic_nent;
12530 ++entry)
12532 if (entry->d_tag == DT_SYMINENT)
12534 /* Note: these braces are necessary to avoid a syntax
12535 error from the SunOS4 C compiler. */
12536 /* PR binutils/17531: A corrupt file can trigger this test.
12537 So do not use an assert, instead generate an error message. */
12538 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
12539 error (_("Bad value (%d) for SYMINENT entry\n"),
12540 (int) entry->d_un.d_val);
12542 else if (entry->d_tag == DT_SYMINSZ)
12543 syminsz = entry->d_un.d_val;
12544 else if (entry->d_tag == DT_SYMINFO)
12545 filedata->dynamic_syminfo_offset
12546 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
12549 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
12551 Elf_External_Syminfo * extsyminfo;
12552 Elf_External_Syminfo * extsym;
12553 Elf_Internal_Syminfo * syminfo;
12555 /* There is a syminfo section. Read the data. */
12556 extsyminfo = (Elf_External_Syminfo *)
12557 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
12558 1, syminsz, _("symbol information"));
12559 if (!extsyminfo)
12560 return false;
12562 if (filedata->dynamic_syminfo != NULL)
12564 error (_("Multiple dynamic symbol information sections found\n"));
12565 free (filedata->dynamic_syminfo);
12567 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
12568 if (filedata->dynamic_syminfo == NULL)
12570 error (_("Out of memory allocating %" PRIu64
12571 " bytes for dynamic symbol info\n"),
12572 syminsz);
12573 return false;
12576 filedata->dynamic_syminfo_nent
12577 = syminsz / sizeof (Elf_External_Syminfo);
12578 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
12579 syminfo < (filedata->dynamic_syminfo
12580 + filedata->dynamic_syminfo_nent);
12581 ++syminfo, ++extsym)
12583 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
12584 syminfo->si_flags = BYTE_GET (extsym->si_flags);
12587 free (extsyminfo);
12591 if (do_dynamic && filedata->dynamic_addr)
12593 if (filedata->is_separate)
12594 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
12595 "\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
12596 filedata->dynamic_nent),
12597 filedata->file_name,
12598 filedata->dynamic_addr,
12599 filedata->dynamic_nent);
12600 else
12601 printf (ngettext ("\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
12602 "\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
12603 filedata->dynamic_nent),
12604 filedata->dynamic_addr,
12605 filedata->dynamic_nent);
12607 if (do_dynamic)
12608 printf (_(" Tag Type Name/Value\n"));
12610 for (entry = filedata->dynamic_section;
12611 entry < filedata->dynamic_section + filedata->dynamic_nent;
12612 entry++)
12614 if (do_dynamic)
12616 const char * dtype;
12618 putchar (' ');
12619 print_vma (entry->d_tag, FULL_HEX);
12620 dtype = get_dynamic_type (filedata, entry->d_tag);
12621 printf (" (%s)%*s", dtype,
12622 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
12625 switch (entry->d_tag)
12627 case DT_FLAGS:
12628 if (do_dynamic)
12629 print_dynamic_flags (entry->d_un.d_val);
12630 break;
12632 case DT_AUXILIARY:
12633 case DT_FILTER:
12634 case DT_CONFIG:
12635 case DT_DEPAUDIT:
12636 case DT_AUDIT:
12637 if (do_dynamic)
12639 switch (entry->d_tag)
12641 case DT_AUXILIARY:
12642 printf (_("Auxiliary library"));
12643 break;
12645 case DT_FILTER:
12646 printf (_("Filter library"));
12647 break;
12649 case DT_CONFIG:
12650 printf (_("Configuration file"));
12651 break;
12653 case DT_DEPAUDIT:
12654 printf (_("Dependency audit library"));
12655 break;
12657 case DT_AUDIT:
12658 printf (_("Audit library"));
12659 break;
12662 if (valid_dynamic_name (filedata, entry->d_un.d_val))
12663 printf (": [%s]\n",
12664 get_dynamic_name (filedata, entry->d_un.d_val));
12665 else
12667 printf (": ");
12668 print_vma (entry->d_un.d_val, PREFIX_HEX);
12669 putchar ('\n');
12672 break;
12674 case DT_FEATURE:
12675 if (do_dynamic)
12677 printf (_("Flags:"));
12679 if (entry->d_un.d_val == 0)
12680 printf (_(" None\n"));
12681 else
12683 uint64_t val = entry->d_un.d_val;
12685 if (val & DTF_1_PARINIT)
12687 printf (" PARINIT");
12688 val ^= DTF_1_PARINIT;
12690 if (val & DTF_1_CONFEXP)
12692 printf (" CONFEXP");
12693 val ^= DTF_1_CONFEXP;
12695 if (val != 0)
12696 printf (" %" PRIx64, val);
12697 puts ("");
12700 break;
12702 case DT_POSFLAG_1:
12703 if (do_dynamic)
12705 printf (_("Flags:"));
12707 if (entry->d_un.d_val == 0)
12708 printf (_(" None\n"));
12709 else
12711 uint64_t val = entry->d_un.d_val;
12713 if (val & DF_P1_LAZYLOAD)
12715 printf (" LAZYLOAD");
12716 val ^= DF_P1_LAZYLOAD;
12718 if (val & DF_P1_GROUPPERM)
12720 printf (" GROUPPERM");
12721 val ^= DF_P1_GROUPPERM;
12723 if (val != 0)
12724 printf (" %" PRIx64, val);
12725 puts ("");
12728 break;
12730 case DT_FLAGS_1:
12731 if (do_dynamic)
12733 printf (_("Flags:"));
12734 if (entry->d_un.d_val == 0)
12735 printf (_(" None\n"));
12736 else
12738 uint64_t val = entry->d_un.d_val;
12740 if (val & DF_1_NOW)
12742 printf (" NOW");
12743 val ^= DF_1_NOW;
12745 if (val & DF_1_GLOBAL)
12747 printf (" GLOBAL");
12748 val ^= DF_1_GLOBAL;
12750 if (val & DF_1_GROUP)
12752 printf (" GROUP");
12753 val ^= DF_1_GROUP;
12755 if (val & DF_1_NODELETE)
12757 printf (" NODELETE");
12758 val ^= DF_1_NODELETE;
12760 if (val & DF_1_LOADFLTR)
12762 printf (" LOADFLTR");
12763 val ^= DF_1_LOADFLTR;
12765 if (val & DF_1_INITFIRST)
12767 printf (" INITFIRST");
12768 val ^= DF_1_INITFIRST;
12770 if (val & DF_1_NOOPEN)
12772 printf (" NOOPEN");
12773 val ^= DF_1_NOOPEN;
12775 if (val & DF_1_ORIGIN)
12777 printf (" ORIGIN");
12778 val ^= DF_1_ORIGIN;
12780 if (val & DF_1_DIRECT)
12782 printf (" DIRECT");
12783 val ^= DF_1_DIRECT;
12785 if (val & DF_1_TRANS)
12787 printf (" TRANS");
12788 val ^= DF_1_TRANS;
12790 if (val & DF_1_INTERPOSE)
12792 printf (" INTERPOSE");
12793 val ^= DF_1_INTERPOSE;
12795 if (val & DF_1_NODEFLIB)
12797 printf (" NODEFLIB");
12798 val ^= DF_1_NODEFLIB;
12800 if (val & DF_1_NODUMP)
12802 printf (" NODUMP");
12803 val ^= DF_1_NODUMP;
12805 if (val & DF_1_CONFALT)
12807 printf (" CONFALT");
12808 val ^= DF_1_CONFALT;
12810 if (val & DF_1_ENDFILTEE)
12812 printf (" ENDFILTEE");
12813 val ^= DF_1_ENDFILTEE;
12815 if (val & DF_1_DISPRELDNE)
12817 printf (" DISPRELDNE");
12818 val ^= DF_1_DISPRELDNE;
12820 if (val & DF_1_DISPRELPND)
12822 printf (" DISPRELPND");
12823 val ^= DF_1_DISPRELPND;
12825 if (val & DF_1_NODIRECT)
12827 printf (" NODIRECT");
12828 val ^= DF_1_NODIRECT;
12830 if (val & DF_1_IGNMULDEF)
12832 printf (" IGNMULDEF");
12833 val ^= DF_1_IGNMULDEF;
12835 if (val & DF_1_NOKSYMS)
12837 printf (" NOKSYMS");
12838 val ^= DF_1_NOKSYMS;
12840 if (val & DF_1_NOHDR)
12842 printf (" NOHDR");
12843 val ^= DF_1_NOHDR;
12845 if (val & DF_1_EDITED)
12847 printf (" EDITED");
12848 val ^= DF_1_EDITED;
12850 if (val & DF_1_NORELOC)
12852 printf (" NORELOC");
12853 val ^= DF_1_NORELOC;
12855 if (val & DF_1_SYMINTPOSE)
12857 printf (" SYMINTPOSE");
12858 val ^= DF_1_SYMINTPOSE;
12860 if (val & DF_1_GLOBAUDIT)
12862 printf (" GLOBAUDIT");
12863 val ^= DF_1_GLOBAUDIT;
12865 if (val & DF_1_SINGLETON)
12867 printf (" SINGLETON");
12868 val ^= DF_1_SINGLETON;
12870 if (val & DF_1_STUB)
12872 printf (" STUB");
12873 val ^= DF_1_STUB;
12875 if (val & DF_1_PIE)
12877 printf (" PIE");
12878 val ^= DF_1_PIE;
12880 if (val & DF_1_KMOD)
12882 printf (" KMOD");
12883 val ^= DF_1_KMOD;
12885 if (val & DF_1_WEAKFILTER)
12887 printf (" WEAKFILTER");
12888 val ^= DF_1_WEAKFILTER;
12890 if (val & DF_1_NOCOMMON)
12892 printf (" NOCOMMON");
12893 val ^= DF_1_NOCOMMON;
12895 if (val != 0)
12896 printf (" %" PRIx64, val);
12897 puts ("");
12900 break;
12902 case DT_PLTREL:
12903 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
12904 if (do_dynamic)
12905 puts (get_dynamic_type (filedata, entry->d_un.d_val));
12906 break;
12908 case DT_NULL :
12909 case DT_NEEDED :
12910 case DT_PLTGOT :
12911 case DT_HASH :
12912 case DT_STRTAB :
12913 case DT_SYMTAB :
12914 case DT_RELA :
12915 case DT_INIT :
12916 case DT_FINI :
12917 case DT_SONAME :
12918 case DT_RPATH :
12919 case DT_SYMBOLIC:
12920 case DT_REL :
12921 case DT_RELR :
12922 case DT_DEBUG :
12923 case DT_TEXTREL :
12924 case DT_JMPREL :
12925 case DT_RUNPATH :
12926 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
12928 if (do_dynamic)
12930 const char *name;
12932 if (valid_dynamic_name (filedata, entry->d_un.d_val))
12933 name = get_dynamic_name (filedata, entry->d_un.d_val);
12934 else
12935 name = NULL;
12937 if (name)
12939 switch (entry->d_tag)
12941 case DT_NEEDED:
12942 printf (_("Shared library: [%s]"), name);
12944 if (filedata->program_interpreter
12945 && streq (name, filedata->program_interpreter))
12946 printf (_(" program interpreter"));
12947 break;
12949 case DT_SONAME:
12950 printf (_("Library soname: [%s]"), name);
12951 break;
12953 case DT_RPATH:
12954 printf (_("Library rpath: [%s]"), name);
12955 break;
12957 case DT_RUNPATH:
12958 printf (_("Library runpath: [%s]"), name);
12959 break;
12961 default:
12962 print_vma (entry->d_un.d_val, PREFIX_HEX);
12963 break;
12966 else
12967 print_vma (entry->d_un.d_val, PREFIX_HEX);
12969 putchar ('\n');
12971 break;
12973 case DT_PLTRELSZ:
12974 case DT_RELASZ :
12975 case DT_STRSZ :
12976 case DT_RELSZ :
12977 case DT_RELAENT :
12978 case DT_RELRENT :
12979 case DT_RELRSZ :
12980 case DT_SYMENT :
12981 case DT_RELENT :
12982 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
12983 /* Fall through. */
12984 case DT_PLTPADSZ:
12985 case DT_MOVEENT :
12986 case DT_MOVESZ :
12987 case DT_PREINIT_ARRAYSZ:
12988 case DT_INIT_ARRAYSZ:
12989 case DT_FINI_ARRAYSZ:
12990 case DT_GNU_CONFLICTSZ:
12991 case DT_GNU_LIBLISTSZ:
12992 if (do_dynamic)
12994 print_vma (entry->d_un.d_val, UNSIGNED);
12995 printf (_(" (bytes)\n"));
12997 break;
12999 case DT_VERDEFNUM:
13000 case DT_VERNEEDNUM:
13001 case DT_RELACOUNT:
13002 case DT_RELCOUNT:
13003 if (do_dynamic)
13005 print_vma (entry->d_un.d_val, UNSIGNED);
13006 putchar ('\n');
13008 break;
13010 case DT_SYMINSZ:
13011 case DT_SYMINENT:
13012 case DT_SYMINFO:
13013 case DT_USED:
13014 case DT_INIT_ARRAY:
13015 case DT_FINI_ARRAY:
13016 if (do_dynamic)
13018 if (entry->d_tag == DT_USED
13019 && valid_dynamic_name (filedata, entry->d_un.d_val))
13021 const char *name
13022 = get_dynamic_name (filedata, entry->d_un.d_val);
13024 if (*name)
13026 printf (_("Not needed object: [%s]\n"), name);
13027 break;
13031 print_vma (entry->d_un.d_val, PREFIX_HEX);
13032 putchar ('\n');
13034 break;
13036 case DT_BIND_NOW:
13037 /* The value of this entry is ignored. */
13038 if (do_dynamic)
13039 putchar ('\n');
13040 break;
13042 case DT_GNU_PRELINKED:
13043 if (do_dynamic)
13045 struct tm * tmp;
13046 time_t atime = entry->d_un.d_val;
13048 tmp = gmtime (&atime);
13049 /* PR 17533 file: 041-1244816-0.004. */
13050 if (tmp == NULL)
13051 printf (_("<corrupt time val: %" PRIx64),
13052 (uint64_t) atime);
13053 else
13054 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
13055 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
13056 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
13059 break;
13061 case DT_GNU_HASH:
13062 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
13063 if (do_dynamic)
13065 print_vma (entry->d_un.d_val, PREFIX_HEX);
13066 putchar ('\n');
13068 break;
13070 case DT_GNU_FLAGS_1:
13071 if (do_dynamic)
13073 printf (_("Flags:"));
13074 if (entry->d_un.d_val == 0)
13075 printf (_(" None\n"));
13076 else
13078 uint64_t val = entry->d_un.d_val;
13080 if (val & DF_GNU_1_UNIQUE)
13082 printf (" UNIQUE");
13083 val ^= DF_GNU_1_UNIQUE;
13085 if (val != 0)
13086 printf (" %" PRIx64, val);
13087 puts ("");
13090 break;
13092 default:
13093 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
13094 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
13095 = entry->d_un.d_val;
13097 if (do_dynamic)
13099 switch (filedata->file_header.e_machine)
13101 case EM_AARCH64:
13102 dynamic_section_aarch64_val (entry);
13103 break;
13104 case EM_MIPS:
13105 case EM_MIPS_RS3_LE:
13106 dynamic_section_mips_val (filedata, entry);
13107 break;
13108 case EM_PARISC:
13109 dynamic_section_parisc_val (entry);
13110 break;
13111 case EM_IA_64:
13112 dynamic_section_ia64_val (entry);
13113 break;
13114 default:
13115 print_vma (entry->d_un.d_val, PREFIX_HEX);
13116 putchar ('\n');
13119 break;
13123 return true;
13126 static char *
13127 get_ver_flags (unsigned int flags)
13129 static char buff[128];
13131 buff[0] = 0;
13133 if (flags == 0)
13134 return _("none");
13136 if (flags & VER_FLG_BASE)
13137 strcat (buff, "BASE");
13139 if (flags & VER_FLG_WEAK)
13141 if (flags & VER_FLG_BASE)
13142 strcat (buff, " | ");
13144 strcat (buff, "WEAK");
13147 if (flags & VER_FLG_INFO)
13149 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
13150 strcat (buff, " | ");
13152 strcat (buff, "INFO");
13155 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
13157 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
13158 strcat (buff, " | ");
13160 strcat (buff, _("<unknown>"));
13163 return buff;
13166 /* Display the contents of the version sections. */
13168 static bool
13169 process_version_sections (Filedata * filedata)
13171 Elf_Internal_Shdr * section;
13172 unsigned i;
13173 bool found = false;
13175 if (! do_version)
13176 return true;
13178 for (i = 0, section = filedata->section_headers;
13179 i < filedata->file_header.e_shnum;
13180 i++, section++)
13182 switch (section->sh_type)
13184 case SHT_GNU_verdef:
13186 Elf_External_Verdef * edefs;
13187 size_t idx;
13188 size_t cnt;
13189 char * endbuf;
13191 found = true;
13193 if (filedata->is_separate)
13194 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
13195 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
13196 section->sh_info),
13197 filedata->file_name,
13198 printable_section_name (filedata, section),
13199 section->sh_info);
13200 else
13201 printf (ngettext ("\nVersion definition section '%s' "
13202 "contains %u entry:\n",
13203 "\nVersion definition section '%s' "
13204 "contains %u entries:\n",
13205 section->sh_info),
13206 printable_section_name (filedata, section),
13207 section->sh_info);
13209 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
13210 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
13211 section->sh_offset, section->sh_link,
13212 printable_section_name_from_index (filedata, section->sh_link, NULL));
13214 edefs = (Elf_External_Verdef *)
13215 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
13216 _("version definition section"));
13217 if (!edefs)
13218 break;
13219 endbuf = (char *) edefs + section->sh_size;
13221 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
13223 char * vstart;
13224 Elf_External_Verdef * edef;
13225 Elf_Internal_Verdef ent;
13226 Elf_External_Verdaux * eaux;
13227 Elf_Internal_Verdaux aux;
13228 size_t isum;
13229 int j;
13231 vstart = ((char *) edefs) + idx;
13232 if (vstart + sizeof (*edef) > endbuf)
13233 break;
13235 edef = (Elf_External_Verdef *) vstart;
13237 ent.vd_version = BYTE_GET (edef->vd_version);
13238 ent.vd_flags = BYTE_GET (edef->vd_flags);
13239 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
13240 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
13241 ent.vd_hash = BYTE_GET (edef->vd_hash);
13242 ent.vd_aux = BYTE_GET (edef->vd_aux);
13243 ent.vd_next = BYTE_GET (edef->vd_next);
13245 printf (_(" %#06zx: Rev: %d Flags: %s"),
13246 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
13248 printf (_(" Index: %d Cnt: %d "),
13249 ent.vd_ndx, ent.vd_cnt);
13251 /* Check for overflow. */
13252 if (ent.vd_aux > (size_t) (endbuf - vstart))
13253 break;
13255 vstart += ent.vd_aux;
13257 if (vstart + sizeof (*eaux) > endbuf)
13258 break;
13259 eaux = (Elf_External_Verdaux *) vstart;
13261 aux.vda_name = BYTE_GET (eaux->vda_name);
13262 aux.vda_next = BYTE_GET (eaux->vda_next);
13264 if (valid_dynamic_name (filedata, aux.vda_name))
13265 printf (_("Name: %s\n"),
13266 get_dynamic_name (filedata, aux.vda_name));
13267 else
13268 printf (_("Name index: %ld\n"), aux.vda_name);
13270 isum = idx + ent.vd_aux;
13272 for (j = 1; j < ent.vd_cnt; j++)
13274 if (aux.vda_next < sizeof (*eaux)
13275 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
13277 warn (_("Invalid vda_next field of %lx\n"),
13278 aux.vda_next);
13279 j = ent.vd_cnt;
13280 break;
13282 /* Check for overflow. */
13283 if (aux.vda_next > (size_t) (endbuf - vstart))
13284 break;
13286 isum += aux.vda_next;
13287 vstart += aux.vda_next;
13289 if (vstart + sizeof (*eaux) > endbuf)
13290 break;
13291 eaux = (Elf_External_Verdaux *) vstart;
13293 aux.vda_name = BYTE_GET (eaux->vda_name);
13294 aux.vda_next = BYTE_GET (eaux->vda_next);
13296 if (valid_dynamic_name (filedata, aux.vda_name))
13297 printf (_(" %#06zx: Parent %d: %s\n"),
13298 isum, j,
13299 get_dynamic_name (filedata, aux.vda_name));
13300 else
13301 printf (_(" %#06zx: Parent %d, name index: %ld\n"),
13302 isum, j, aux.vda_name);
13305 if (j < ent.vd_cnt)
13306 printf (_(" Version def aux past end of section\n"));
13308 /* PR 17531:
13309 file: id:000001,src:000172+005151,op:splice,rep:2. */
13310 if (ent.vd_next < sizeof (*edef)
13311 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
13313 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
13314 cnt = section->sh_info;
13315 break;
13317 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
13318 break;
13320 idx += ent.vd_next;
13323 if (cnt < section->sh_info)
13324 printf (_(" Version definition past end of section\n"));
13326 free (edefs);
13328 break;
13330 case SHT_GNU_verneed:
13332 Elf_External_Verneed * eneed;
13333 size_t idx;
13334 size_t cnt;
13335 char * endbuf;
13337 found = true;
13339 if (filedata->is_separate)
13340 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
13341 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
13342 section->sh_info),
13343 filedata->file_name,
13344 printable_section_name (filedata, section),
13345 section->sh_info);
13346 else
13347 printf (ngettext ("\nVersion needs section '%s' "
13348 "contains %u entry:\n",
13349 "\nVersion needs section '%s' "
13350 "contains %u entries:\n",
13351 section->sh_info),
13352 printable_section_name (filedata, section),
13353 section->sh_info);
13355 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
13356 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
13357 section->sh_offset, section->sh_link,
13358 printable_section_name_from_index (filedata, section->sh_link, NULL));
13360 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
13361 section->sh_offset, 1,
13362 section->sh_size,
13363 _("Version Needs section"));
13364 if (!eneed)
13365 break;
13366 endbuf = (char *) eneed + section->sh_size;
13368 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
13370 Elf_External_Verneed * entry;
13371 Elf_Internal_Verneed ent;
13372 size_t isum;
13373 int j;
13374 char * vstart;
13376 vstart = ((char *) eneed) + idx;
13377 if (vstart + sizeof (*entry) > endbuf)
13378 break;
13380 entry = (Elf_External_Verneed *) vstart;
13382 ent.vn_version = BYTE_GET (entry->vn_version);
13383 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
13384 ent.vn_file = BYTE_GET (entry->vn_file);
13385 ent.vn_aux = BYTE_GET (entry->vn_aux);
13386 ent.vn_next = BYTE_GET (entry->vn_next);
13388 printf (_(" %#06zx: Version: %d"), idx, ent.vn_version);
13390 if (valid_dynamic_name (filedata, ent.vn_file))
13391 printf (_(" File: %s"),
13392 get_dynamic_name (filedata, ent.vn_file));
13393 else
13394 printf (_(" File: %lx"), ent.vn_file);
13396 printf (_(" Cnt: %d\n"), ent.vn_cnt);
13398 /* Check for overflow. */
13399 if (ent.vn_aux > (size_t) (endbuf - vstart))
13400 break;
13401 vstart += ent.vn_aux;
13403 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
13405 Elf_External_Vernaux * eaux;
13406 Elf_Internal_Vernaux aux;
13408 if (vstart + sizeof (*eaux) > endbuf)
13409 break;
13410 eaux = (Elf_External_Vernaux *) vstart;
13412 aux.vna_hash = BYTE_GET (eaux->vna_hash);
13413 aux.vna_flags = BYTE_GET (eaux->vna_flags);
13414 aux.vna_other = BYTE_GET (eaux->vna_other);
13415 aux.vna_name = BYTE_GET (eaux->vna_name);
13416 aux.vna_next = BYTE_GET (eaux->vna_next);
13418 if (valid_dynamic_name (filedata, aux.vna_name))
13419 printf (_(" %#06zx: Name: %s"),
13420 isum, get_dynamic_name (filedata, aux.vna_name));
13421 else
13422 printf (_(" %#06zx: Name index: %lx"),
13423 isum, aux.vna_name);
13425 printf (_(" Flags: %s Version: %d\n"),
13426 get_ver_flags (aux.vna_flags), aux.vna_other);
13428 if (aux.vna_next < sizeof (*eaux)
13429 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
13431 warn (_("Invalid vna_next field of %lx\n"),
13432 aux.vna_next);
13433 j = ent.vn_cnt;
13434 break;
13436 /* Check for overflow. */
13437 if (aux.vna_next > (size_t) (endbuf - vstart))
13438 break;
13439 isum += aux.vna_next;
13440 vstart += aux.vna_next;
13443 if (j < ent.vn_cnt)
13444 warn (_("Missing Version Needs auxiliary information\n"));
13446 if (ent.vn_next < sizeof (*entry)
13447 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
13449 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
13450 cnt = section->sh_info;
13451 break;
13453 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
13454 break;
13455 idx += ent.vn_next;
13458 if (cnt < section->sh_info)
13459 warn (_("Missing Version Needs information\n"));
13461 free (eneed);
13463 break;
13465 case SHT_GNU_versym:
13467 Elf_Internal_Shdr * link_section;
13468 uint64_t total;
13469 unsigned int cnt;
13470 unsigned char * edata;
13471 unsigned short * data;
13472 char * strtab;
13473 Elf_Internal_Sym * symbols;
13474 Elf_Internal_Shdr * string_sec;
13475 uint64_t num_syms;
13476 uint64_t off;
13478 if (section->sh_link >= filedata->file_header.e_shnum)
13479 break;
13481 link_section = filedata->section_headers + section->sh_link;
13482 total = section->sh_size / sizeof (Elf_External_Versym);
13484 if (link_section->sh_link >= filedata->file_header.e_shnum)
13485 break;
13487 found = true;
13489 symbols = get_elf_symbols (filedata, link_section, & num_syms);
13490 if (symbols == NULL)
13491 break;
13493 string_sec = filedata->section_headers + link_section->sh_link;
13495 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
13496 string_sec->sh_size,
13497 _("version string table"));
13498 if (!strtab)
13500 free (symbols);
13501 break;
13504 if (filedata->is_separate)
13505 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entry:\n",
13506 "\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entries:\n",
13507 total),
13508 filedata->file_name,
13509 printable_section_name (filedata, section),
13510 total);
13511 else
13512 printf (ngettext ("\nVersion symbols section '%s' "
13513 "contains %" PRIu64 " entry:\n",
13514 "\nVersion symbols section '%s' "
13515 "contains %" PRIu64 " entries:\n",
13516 total),
13517 printable_section_name (filedata, section),
13518 total);
13520 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
13521 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
13522 section->sh_offset, section->sh_link,
13523 printable_section_name (filedata, link_section));
13525 off = offset_from_vma (filedata,
13526 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
13527 total * sizeof (short));
13528 edata = (unsigned char *) get_data (NULL, filedata, off,
13529 sizeof (short), total,
13530 _("version symbol data"));
13531 if (!edata)
13533 free (strtab);
13534 free (symbols);
13535 break;
13538 data = (short unsigned int *) cmalloc (total, sizeof (short));
13540 for (cnt = total; cnt --;)
13541 data[cnt] = byte_get (edata + cnt * sizeof (short),
13542 sizeof (short));
13544 free (edata);
13546 for (cnt = 0; cnt < total; cnt += 4)
13548 int j, nn;
13549 char *name;
13550 char *invalid = _("*invalid*");
13552 printf (" %03x:", cnt);
13554 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
13555 switch (data[cnt + j])
13557 case 0:
13558 fputs (_(" 0 (*local*) "), stdout);
13559 break;
13561 case 1:
13562 fputs (_(" 1 (*global*) "), stdout);
13563 break;
13565 default:
13566 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
13567 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
13569 /* If this index value is greater than the size of the symbols
13570 array, break to avoid an out-of-bounds read. */
13571 if (cnt + j >= num_syms)
13573 warn (_("invalid index into symbol array\n"));
13574 break;
13577 name = NULL;
13578 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
13580 Elf_Internal_Verneed ivn;
13581 uint64_t offset;
13583 offset = offset_from_vma
13584 (filedata,
13585 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
13586 sizeof (Elf_External_Verneed));
13590 Elf_Internal_Vernaux ivna;
13591 Elf_External_Verneed evn;
13592 Elf_External_Vernaux evna;
13593 uint64_t a_off;
13595 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
13596 _("version need")) == NULL)
13597 break;
13599 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13600 ivn.vn_next = BYTE_GET (evn.vn_next);
13602 a_off = offset + ivn.vn_aux;
13606 if (get_data (&evna, filedata, a_off, sizeof (evna),
13607 1, _("version need aux (2)")) == NULL)
13609 ivna.vna_next = 0;
13610 ivna.vna_other = 0;
13612 else
13614 ivna.vna_next = BYTE_GET (evna.vna_next);
13615 ivna.vna_other = BYTE_GET (evna.vna_other);
13618 a_off += ivna.vna_next;
13620 while (ivna.vna_other != data[cnt + j]
13621 && ivna.vna_next != 0);
13623 if (ivna.vna_other == data[cnt + j])
13625 ivna.vna_name = BYTE_GET (evna.vna_name);
13627 if (ivna.vna_name >= string_sec->sh_size)
13628 name = invalid;
13629 else
13630 name = strtab + ivna.vna_name;
13631 break;
13634 offset += ivn.vn_next;
13636 while (ivn.vn_next);
13639 if (data[cnt + j] != 0x8001
13640 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
13642 Elf_Internal_Verdef ivd;
13643 Elf_External_Verdef evd;
13644 uint64_t offset;
13646 offset = offset_from_vma
13647 (filedata,
13648 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
13649 sizeof evd);
13653 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
13654 _("version def")) == NULL)
13656 ivd.vd_next = 0;
13657 /* PR 17531: file: 046-1082287-0.004. */
13658 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
13659 break;
13661 else
13663 ivd.vd_next = BYTE_GET (evd.vd_next);
13664 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13667 offset += ivd.vd_next;
13669 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
13670 && ivd.vd_next != 0);
13672 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
13674 Elf_External_Verdaux evda;
13675 Elf_Internal_Verdaux ivda;
13677 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13679 if (get_data (&evda, filedata,
13680 offset - ivd.vd_next + ivd.vd_aux,
13681 sizeof (evda), 1,
13682 _("version def aux")) == NULL)
13683 break;
13685 ivda.vda_name = BYTE_GET (evda.vda_name);
13687 if (ivda.vda_name >= string_sec->sh_size)
13688 name = invalid;
13689 else if (name != NULL && name != invalid)
13690 name = _("*both*");
13691 else
13692 name = strtab + ivda.vda_name;
13695 if (name != NULL)
13696 nn += printf ("(%s%-*s",
13697 name,
13698 12 - (int) strlen (name),
13699 ")");
13701 if (nn < 18)
13702 printf ("%*c", 18 - nn, ' ');
13705 putchar ('\n');
13708 free (data);
13709 free (strtab);
13710 free (symbols);
13712 break;
13714 default:
13715 break;
13719 if (! found)
13721 if (filedata->is_separate)
13722 printf (_("\nNo version information found in linked file '%s'.\n"),
13723 filedata->file_name);
13724 else
13725 printf (_("\nNo version information found in this file.\n"));
13728 return true;
13731 static const char *
13732 get_symbol_binding (Filedata * filedata, unsigned int binding)
13734 static char buff[64];
13736 switch (binding)
13738 case STB_LOCAL: return "LOCAL";
13739 case STB_GLOBAL: return "GLOBAL";
13740 case STB_WEAK: return "WEAK";
13741 default:
13742 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
13743 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
13744 binding);
13745 else if (binding >= STB_LOOS && binding <= STB_HIOS)
13747 if (binding == STB_GNU_UNIQUE
13748 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
13749 return "UNIQUE";
13750 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
13752 else
13753 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
13754 return buff;
13758 static const char *
13759 get_symbol_type (Filedata * filedata, unsigned int type)
13761 static char buff[64];
13763 switch (type)
13765 case STT_NOTYPE: return "NOTYPE";
13766 case STT_OBJECT: return "OBJECT";
13767 case STT_FUNC: return "FUNC";
13768 case STT_SECTION: return "SECTION";
13769 case STT_FILE: return "FILE";
13770 case STT_COMMON: return "COMMON";
13771 case STT_TLS: return "TLS";
13772 case STT_RELC: return "RELC";
13773 case STT_SRELC: return "SRELC";
13774 default:
13775 if (type >= STT_LOPROC && type <= STT_HIPROC)
13777 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
13778 return "THUMB_FUNC";
13780 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
13781 return "REGISTER";
13783 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
13784 return "PARISC_MILLI";
13786 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
13788 else if (type >= STT_LOOS && type <= STT_HIOS)
13790 if (filedata->file_header.e_machine == EM_PARISC)
13792 if (type == STT_HP_OPAQUE)
13793 return "HP_OPAQUE";
13794 if (type == STT_HP_STUB)
13795 return "HP_STUB";
13798 if (type == STT_GNU_IFUNC
13799 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
13800 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
13801 return "IFUNC";
13803 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
13805 else
13806 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
13807 return buff;
13811 static const char *
13812 get_symbol_visibility (unsigned int visibility)
13814 switch (visibility)
13816 case STV_DEFAULT: return "DEFAULT";
13817 case STV_INTERNAL: return "INTERNAL";
13818 case STV_HIDDEN: return "HIDDEN";
13819 case STV_PROTECTED: return "PROTECTED";
13820 default:
13821 error (_("Unrecognized visibility value: %u\n"), visibility);
13822 return _("<unknown>");
13826 static const char *
13827 get_alpha_symbol_other (unsigned int other)
13829 switch (other)
13831 case STO_ALPHA_NOPV: return "NOPV";
13832 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
13833 default:
13834 error (_("Unrecognized alpha specific other value: %u\n"), other);
13835 return _("<unknown>");
13839 static const char *
13840 get_solaris_symbol_visibility (unsigned int visibility)
13842 switch (visibility)
13844 case 4: return "EXPORTED";
13845 case 5: return "SINGLETON";
13846 case 6: return "ELIMINATE";
13847 default: return get_symbol_visibility (visibility);
13851 static const char *
13852 get_aarch64_symbol_other (unsigned int other)
13854 static char buf[32];
13856 if (other & STO_AARCH64_VARIANT_PCS)
13858 other &= ~STO_AARCH64_VARIANT_PCS;
13859 if (other == 0)
13860 return "VARIANT_PCS";
13861 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
13862 return buf;
13864 return NULL;
13867 static const char *
13868 get_mips_symbol_other (unsigned int other)
13870 switch (other)
13872 case STO_OPTIONAL: return "OPTIONAL";
13873 case STO_MIPS_PLT: return "MIPS PLT";
13874 case STO_MIPS_PIC: return "MIPS PIC";
13875 case STO_MICROMIPS: return "MICROMIPS";
13876 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
13877 case STO_MIPS16: return "MIPS16";
13878 default: return NULL;
13882 static const char *
13883 get_ia64_symbol_other (Filedata * filedata, unsigned int other)
13885 if (is_ia64_vms (filedata))
13887 static char res[32];
13889 res[0] = 0;
13891 /* Function types is for images and .STB files only. */
13892 switch (filedata->file_header.e_type)
13894 case ET_DYN:
13895 case ET_EXEC:
13896 switch (VMS_ST_FUNC_TYPE (other))
13898 case VMS_SFT_CODE_ADDR:
13899 strcat (res, " CA");
13900 break;
13901 case VMS_SFT_SYMV_IDX:
13902 strcat (res, " VEC");
13903 break;
13904 case VMS_SFT_FD:
13905 strcat (res, " FD");
13906 break;
13907 case VMS_SFT_RESERVE:
13908 strcat (res, " RSV");
13909 break;
13910 default:
13911 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
13912 VMS_ST_FUNC_TYPE (other));
13913 strcat (res, " <unknown>");
13914 break;
13916 break;
13917 default:
13918 break;
13920 switch (VMS_ST_LINKAGE (other))
13922 case VMS_STL_IGNORE:
13923 strcat (res, " IGN");
13924 break;
13925 case VMS_STL_RESERVE:
13926 strcat (res, " RSV");
13927 break;
13928 case VMS_STL_STD:
13929 strcat (res, " STD");
13930 break;
13931 case VMS_STL_LNK:
13932 strcat (res, " LNK");
13933 break;
13934 default:
13935 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
13936 VMS_ST_LINKAGE (other));
13937 strcat (res, " <unknown>");
13938 break;
13941 if (res[0] != 0)
13942 return res + 1;
13943 else
13944 return res;
13946 return NULL;
13949 static const char *
13950 get_ppc64_symbol_other (unsigned int other)
13952 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
13953 return NULL;
13955 other >>= STO_PPC64_LOCAL_BIT;
13956 if (other <= 6)
13958 static char buf[64];
13959 if (other >= 2)
13960 other = ppc64_decode_local_entry (other);
13961 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
13962 return buf;
13964 return NULL;
13967 static const char *
13968 get_riscv_symbol_other (unsigned int other)
13970 static char buf[32];
13971 buf[0] = 0;
13973 if (other & STO_RISCV_VARIANT_CC)
13975 strcat (buf, _(" VARIANT_CC"));
13976 other &= ~STO_RISCV_VARIANT_CC;
13979 if (other != 0)
13980 snprintf (buf, sizeof buf, " %x", other);
13983 if (buf[0] != 0)
13984 return buf + 1;
13985 else
13986 return buf;
13989 static const char *
13990 get_symbol_other (Filedata * filedata, unsigned int other)
13992 const char * result = NULL;
13993 static char buff [64];
13995 if (other == 0)
13996 return "";
13998 switch (filedata->file_header.e_machine)
14000 case EM_ALPHA:
14001 result = get_alpha_symbol_other (other);
14002 break;
14003 case EM_AARCH64:
14004 result = get_aarch64_symbol_other (other);
14005 break;
14006 case EM_MIPS:
14007 result = get_mips_symbol_other (other);
14008 break;
14009 case EM_IA_64:
14010 result = get_ia64_symbol_other (filedata, other);
14011 break;
14012 case EM_PPC64:
14013 result = get_ppc64_symbol_other (other);
14014 break;
14015 case EM_RISCV:
14016 result = get_riscv_symbol_other (other);
14017 break;
14018 default:
14019 result = NULL;
14020 break;
14023 if (result)
14024 return result;
14026 snprintf (buff, sizeof buff, _("<other>: %x"), other);
14027 return buff;
14030 static const char *
14031 get_symbol_version_string (Filedata *filedata,
14032 bool is_dynsym,
14033 const char *strtab,
14034 size_t strtab_size,
14035 unsigned int si,
14036 Elf_Internal_Sym *psym,
14037 enum versioned_symbol_info *sym_info,
14038 unsigned short *vna_other)
14040 unsigned char data[2];
14041 unsigned short vers_data;
14042 uint64_t offset;
14043 unsigned short max_vd_ndx;
14045 if (!is_dynsym
14046 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
14047 return NULL;
14049 offset = offset_from_vma (filedata,
14050 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
14051 sizeof data + si * sizeof (vers_data));
14053 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
14054 sizeof (data), 1, _("version data")) == NULL)
14055 return NULL;
14057 vers_data = byte_get (data, 2);
14059 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
14060 return NULL;
14062 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
14063 max_vd_ndx = 0;
14065 /* Usually we'd only see verdef for defined symbols, and verneed for
14066 undefined symbols. However, symbols defined by the linker in
14067 .dynbss for variables copied from a shared library in order to
14068 avoid text relocations are defined yet have verneed. We could
14069 use a heuristic to detect the special case, for example, check
14070 for verneed first on symbols defined in SHT_NOBITS sections, but
14071 it is simpler and more reliable to just look for both verdef and
14072 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
14074 if (psym->st_shndx != SHN_UNDEF
14075 && vers_data != 0x8001
14076 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
14078 Elf_Internal_Verdef ivd;
14079 Elf_Internal_Verdaux ivda;
14080 Elf_External_Verdaux evda;
14081 uint64_t off;
14083 off = offset_from_vma (filedata,
14084 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
14085 sizeof (Elf_External_Verdef));
14089 Elf_External_Verdef evd;
14091 if (get_data (&evd, filedata, off, sizeof (evd), 1,
14092 _("version def")) == NULL)
14094 ivd.vd_ndx = 0;
14095 ivd.vd_aux = 0;
14096 ivd.vd_next = 0;
14097 ivd.vd_flags = 0;
14099 else
14101 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
14102 ivd.vd_aux = BYTE_GET (evd.vd_aux);
14103 ivd.vd_next = BYTE_GET (evd.vd_next);
14104 ivd.vd_flags = BYTE_GET (evd.vd_flags);
14107 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
14108 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
14110 off += ivd.vd_next;
14112 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
14114 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
14116 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
14117 return NULL;
14119 off -= ivd.vd_next;
14120 off += ivd.vd_aux;
14122 if (get_data (&evda, filedata, off, sizeof (evda), 1,
14123 _("version def aux")) != NULL)
14125 ivda.vda_name = BYTE_GET (evda.vda_name);
14127 if (psym->st_name != ivda.vda_name)
14128 return (ivda.vda_name < strtab_size
14129 ? strtab + ivda.vda_name : _("<corrupt>"));
14134 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
14136 Elf_External_Verneed evn;
14137 Elf_Internal_Verneed ivn;
14138 Elf_Internal_Vernaux ivna;
14140 offset = offset_from_vma (filedata,
14141 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
14142 sizeof evn);
14145 uint64_t vna_off;
14147 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
14148 _("version need")) == NULL)
14150 ivna.vna_next = 0;
14151 ivna.vna_other = 0;
14152 ivna.vna_name = 0;
14153 break;
14156 ivn.vn_aux = BYTE_GET (evn.vn_aux);
14157 ivn.vn_next = BYTE_GET (evn.vn_next);
14159 vna_off = offset + ivn.vn_aux;
14163 Elf_External_Vernaux evna;
14165 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
14166 _("version need aux (3)")) == NULL)
14168 ivna.vna_next = 0;
14169 ivna.vna_other = 0;
14170 ivna.vna_name = 0;
14172 else
14174 ivna.vna_other = BYTE_GET (evna.vna_other);
14175 ivna.vna_next = BYTE_GET (evna.vna_next);
14176 ivna.vna_name = BYTE_GET (evna.vna_name);
14179 vna_off += ivna.vna_next;
14181 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
14183 if (ivna.vna_other == vers_data)
14184 break;
14186 offset += ivn.vn_next;
14188 while (ivn.vn_next != 0);
14190 if (ivna.vna_other == vers_data)
14192 *sym_info = symbol_undefined;
14193 *vna_other = ivna.vna_other;
14194 return (ivna.vna_name < strtab_size
14195 ? strtab + ivna.vna_name : _("<corrupt>"));
14197 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
14198 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
14199 return _("<corrupt>");
14201 return NULL;
14204 /* Display a symbol size on stdout. Format is based on --sym-base setting. */
14206 static unsigned int
14207 print_symbol_size (uint64_t vma, int base)
14209 switch (base)
14211 case 8:
14212 return print_vma (vma, OCTAL_5);
14214 case 10:
14215 return print_vma (vma, UNSIGNED_5);
14217 case 16:
14218 return print_vma (vma, PREFIX_HEX_5);
14220 case 0:
14221 default:
14222 return print_vma (vma, DEC_5);
14226 /* Print information on a single symbol. */
14228 static void
14229 print_symbol (Filedata * filedata,
14230 uint64_t symbol_index,
14231 Elf_Internal_Sym * symtab,
14232 Elf_Internal_Shdr * section,
14233 char * strtab,
14234 size_t strtab_size)
14236 const char *version_string;
14237 enum versioned_symbol_info sym_info;
14238 unsigned short vna_other;
14239 const char * sstr;
14240 Elf_Internal_Sym *psym = symtab + symbol_index;
14242 /* FIXME: We should have a table of field widths,
14243 rather than using hard coded constants. */
14244 printf ("%6" PRId64 ": ", symbol_index);
14245 print_vma (psym->st_value, LONG_HEX);
14246 putchar (' ');
14247 print_symbol_size (psym->st_size, sym_base);
14248 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
14249 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
14250 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
14251 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
14252 else
14254 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
14256 printf (" %-7s", get_symbol_visibility (vis));
14258 /* Check to see if any other bits in the st_other field are set.
14259 FIXME: Displaying this information here disrupts the layout
14260 of the table being generated. */
14261 if (psym->st_other ^ vis)
14262 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
14265 bool is_special;
14267 sstr = printable_section_name_from_index (filedata, psym->st_shndx, & is_special);
14269 /* Print the symbol's section index. If the index is special
14270 then print the index's name rather than its number. */
14271 if (is_special)
14273 int printed;
14275 /* Special case: If there are no section headers, and the printable
14276 name is "<section 0x...." then just display the section number
14277 as a decimal. This happens when objcopy --strip -section-headers
14278 is used. */
14279 if (filedata->file_header.e_shnum == 0 && startswith (sstr, "<section"))
14280 printed = printf (" %4d ", psym->st_shndx);
14281 else
14282 printed = printf (" %4s ", sstr);
14284 if (extra_sym_info && printed < 16)
14285 printf ("%*s", 16 - printed, "");
14287 else
14289 printf (" %4u ", psym->st_shndx);
14291 if (extra_sym_info)
14293 /* Display the section name referenced by the section index. */
14294 int printed = printf ("(%s) ", sstr);
14295 if (printed < 10)
14296 printf ("%*s", 10 - printed, "");
14300 /* Get the symbol's name. For section symbols without a
14301 specific name use the (already computed) section name. */
14302 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
14303 && section_index_real (filedata, psym->st_shndx)
14304 && psym->st_name == 0)
14308 else
14310 bool is_valid;
14312 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
14313 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
14316 version_string
14317 = get_symbol_version_string (filedata,
14318 (section == NULL
14319 || section->sh_type == SHT_DYNSYM),
14320 strtab, strtab_size, symbol_index,
14321 psym, &sym_info, &vna_other);
14323 int len_avail = 21;
14324 if (! do_wide && version_string != NULL)
14326 char buffer[16];
14328 len_avail -= 1 + strlen (version_string);
14330 if (sym_info == symbol_undefined)
14331 len_avail -= sprintf (buffer," (%d)", vna_other);
14332 else if (sym_info != symbol_hidden)
14333 len_avail -= 1;
14336 print_symbol_name (len_avail, sstr);
14338 if (version_string)
14340 if (sym_info == symbol_undefined)
14341 printf ("@%s (%d)", version_string, vna_other);
14342 else
14343 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
14344 version_string);
14347 putchar ('\n');
14349 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
14350 && section != NULL
14351 && symbol_index >= section->sh_info
14352 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
14353 && filedata->file_header.e_machine != EM_MIPS
14354 /* Solaris binaries have been found to violate this requirement as
14355 well. Not sure if this is a bug or an ABI requirement. */
14356 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
14357 warn (_("local symbol %" PRIu64 " found at index >= %s's sh_info value of %u\n"),
14358 symbol_index, printable_section_name (filedata, section), section->sh_info);
14361 static const char *
14362 get_lto_kind (unsigned int kind)
14364 switch (kind)
14366 case 0: return "DEF";
14367 case 1: return "WEAKDEF";
14368 case 2: return "UNDEF";
14369 case 3: return "WEAKUNDEF";
14370 case 4: return "COMMON";
14371 default:
14372 break;
14375 static char buffer[30];
14376 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
14377 sprintf (buffer, "<unknown: %u>", kind);
14378 return buffer;
14381 static const char *
14382 get_lto_visibility (unsigned int visibility)
14384 switch (visibility)
14386 case 0: return "DEFAULT";
14387 case 1: return "PROTECTED";
14388 case 2: return "INTERNAL";
14389 case 3: return "HIDDEN";
14390 default:
14391 break;
14394 static char buffer[30];
14395 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
14396 sprintf (buffer, "<unknown: %u>", visibility);
14397 return buffer;
14400 static const char *
14401 get_lto_sym_type (unsigned int sym_type)
14403 switch (sym_type)
14405 case 0: return "UNKNOWN";
14406 case 1: return "FUNCTION";
14407 case 2: return "VARIABLE";
14408 default:
14409 break;
14412 static char buffer[30];
14413 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
14414 sprintf (buffer, "<unknown: %u>", sym_type);
14415 return buffer;
14418 /* Display an LTO format symbol table.
14419 FIXME: The format of LTO symbol tables is not formalized.
14420 So this code could need changing in the future. */
14422 static bool
14423 display_lto_symtab (Filedata * filedata,
14424 Elf_Internal_Shdr * section)
14426 if (section->sh_size == 0)
14428 if (filedata->is_separate)
14429 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
14430 printable_section_name (filedata, section),
14431 filedata->file_name);
14432 else
14433 printf (_("\nLTO Symbol table '%s' is empty!\n"),
14434 printable_section_name (filedata, section));
14436 return true;
14439 if (section->sh_size > filedata->file_size)
14441 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
14442 printable_section_name (filedata, section),
14443 section->sh_size);
14444 return false;
14447 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
14448 section->sh_size, 1, _("LTO symbols"));
14449 if (alloced_data == NULL)
14450 return false;
14452 /* Look for extended data for the symbol table. */
14453 void * ext_data_orig = NULL;
14454 char * ext_data = NULL;
14455 char * ext_data_end = NULL;
14456 char *ext_name = xasprintf (".gnu.lto_.ext_symtab.%s",
14457 (section_name (filedata, section)
14458 + sizeof (".gnu.lto_.symtab.")));
14459 Elf_Internal_Shdr *ext = find_section (filedata, ext_name);
14460 if (ext != NULL)
14462 if (ext->sh_size < 3)
14463 error (_("LTO Symbol extension table '%s' is empty!\n"),
14464 printable_section_name (filedata, ext));
14465 else
14467 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
14468 ext->sh_size, 1,
14469 _("LTO ext symbol data"));
14470 if (ext_data != NULL)
14472 ext_data_end = ext_data + ext->sh_size;
14473 if (* ext_data++ != 1)
14474 error (_("Unexpected version number in symbol extension table\n"));
14479 const unsigned char * data = (const unsigned char *) alloced_data;
14480 const unsigned char * end = data + section->sh_size;
14482 if (filedata->is_separate)
14483 printf (_("\nIn linked file '%s': "), filedata->file_name);
14484 else
14485 printf ("\n");
14487 if (ext_data_orig != NULL)
14489 if (do_wide)
14490 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
14491 printable_section_name (filedata, section),
14492 printable_section_name (filedata, ext));
14493 else
14495 printf (_("LTO Symbol table '%s'\n"),
14496 printable_section_name (filedata, section));
14497 printf (_(" and extension table '%s' contain:\n"),
14498 printable_section_name (filedata, ext));
14501 else
14502 printf (_("LTO Symbol table '%s' contains:\n"),
14503 printable_section_name (filedata, section));
14505 /* FIXME: Add a wide version. */
14506 if (ext_data_orig != NULL)
14507 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
14508 else
14509 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
14511 /* FIXME: We do not handle style prefixes. */
14513 while (data < end)
14515 const unsigned char * sym_name = data;
14516 data += strnlen ((const char *) sym_name, end - data) + 1;
14517 if (data >= end)
14518 goto fail;
14520 const unsigned char * comdat_key = data;
14521 data += strnlen ((const char *) comdat_key, end - data) + 1;
14522 if (data >= end)
14523 goto fail;
14525 if (data + 2 + 8 + 4 > end)
14526 goto fail;
14528 unsigned int kind = *data++;
14529 unsigned int visibility = *data++;
14531 uint64_t size = byte_get (data, 8);
14532 data += 8;
14534 uint64_t slot = byte_get (data, 4);
14535 data += 4;
14537 if (ext_data != NULL)
14539 if (ext_data < (ext_data_end - 1))
14541 unsigned int sym_type = * ext_data ++;
14542 unsigned int sec_kind = * ext_data ++;
14544 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " %9s %08x _",
14545 * comdat_key == 0 ? "-" : (char *) comdat_key,
14546 get_lto_kind (kind),
14547 get_lto_visibility (visibility),
14548 size,
14549 slot,
14550 get_lto_sym_type (sym_type),
14551 sec_kind);
14552 print_symbol_name (6, (const char *) sym_name);
14554 else
14556 error (_("Ran out of LTO symbol extension data\n"));
14557 ext_data = NULL;
14558 /* FIXME: return FAIL result ? */
14561 else
14563 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " _",
14564 * comdat_key == 0 ? "-" : (char *) comdat_key,
14565 get_lto_kind (kind),
14566 get_lto_visibility (visibility),
14567 size,
14568 slot);
14569 print_symbol_name (21, (const char *) sym_name);
14571 putchar ('\n');
14574 if (ext_data != NULL && ext_data < ext_data_end)
14576 error (_("Data remains in the LTO symbol extension table\n"));
14577 goto fail;
14580 free (alloced_data);
14581 free (ext_data_orig);
14582 free (ext_name);
14583 return true;
14585 fail:
14586 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
14587 free (alloced_data);
14588 free (ext_data_orig);
14589 free (ext_name);
14590 return false;
14593 /* Display LTO symbol tables. */
14595 static bool
14596 process_lto_symbol_tables (Filedata * filedata)
14598 Elf_Internal_Shdr * section;
14599 unsigned int i;
14600 bool res = true;
14602 if (!do_lto_syms)
14603 return true;
14605 if (filedata->section_headers == NULL)
14606 return true;
14608 for (i = 0, section = filedata->section_headers;
14609 i < filedata->file_header.e_shnum;
14610 i++, section++)
14611 if (section_name_valid (filedata, section)
14612 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
14613 res &= display_lto_symtab (filedata, section);
14615 return res;
14618 static void
14619 print_symbol_table_heading (void)
14621 /* FIXME: We should store the size of each field in the display in a table and
14622 then use the values inside print_symbol(), instead of that function using
14623 hard coded constants. */
14624 if (is_32bit_elf)
14626 if (extra_sym_info)
14628 printf (_(" Num: Value Size Type Bind Vis+Other Ndx(SecName) Name [+ Version Info]\n"));
14629 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |---8--| |----13.....| |........... */
14630 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 (.text) get_sections */
14632 else if (do_wide)
14634 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14635 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |-4| |........... */
14636 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 get_sections */
14638 else
14640 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14641 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |-4| |------------29-------------| */
14642 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 get_sections */
14645 else
14647 if (extra_sym_info)
14649 printf (_(" Num: Value Size Type Bind Vis+Other Ndx(SecName) Name [+ Version Info]\n"));
14650 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-------14---| |..... */
14651 /* eg: 2: 0000000000000000 0 FUNC LOCAL DEFAULT 1 (.text) .very_long_function_name */
14654 else if (do_wide)
14656 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14657 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-4| |........... */
14658 /* eg: 5: 0000000000000000 14 FUNC LOCAL DEFAULT 1 very_long_function_name */
14660 else
14662 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14663 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-4| |--------21---------| */
14664 /* eg: 5: 0000000000000000 14 FUNC LOCAL DEFAULT 1 very_long_functi[...] */
14669 static bool
14670 dump_symbol_section (Elf_Internal_Shdr * section,
14671 Filedata * filedata)
14673 if (section->sh_entsize == 0)
14675 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
14676 printable_section_name (filedata, section));
14677 return false;
14680 uint64_t num_syms = section->sh_size / section->sh_entsize;
14682 if (filedata->is_separate)
14683 printf (ngettext ("\nIn linked file '%s' symbol section '%s'"
14684 " contains %" PRIu64 " entry:\n",
14685 "\nIn linked file '%s' symbol section '%s'"
14686 " contains %" PRIu64 " entries:\n",
14687 num_syms),
14688 filedata->file_name,
14689 printable_section_name (filedata, section),
14690 num_syms);
14691 else
14692 printf (ngettext ("\nSymbol table '%s' contains %" PRIu64
14693 " entry:\n",
14694 "\nSymbol table '%s' contains %" PRIu64
14695 " entries:\n",
14696 num_syms),
14697 printable_section_name (filedata, section),
14698 num_syms);
14700 print_symbol_table_heading ();
14702 Elf_Internal_Sym * symtab = get_elf_symbols (filedata, section, & num_syms);
14703 if (symtab == NULL)
14704 /* An error message will have already been displayed. */
14705 return false;
14707 char * strtab = NULL;
14708 uint64_t strtab_size = 0;
14710 if (section->sh_link == filedata->file_header.e_shstrndx)
14712 strtab = filedata->string_table;
14713 strtab_size = filedata->string_table_length;
14715 else if (section->sh_link < filedata->file_header.e_shnum)
14717 Elf_Internal_Shdr * string_sec;
14719 string_sec = filedata->section_headers + section->sh_link;
14721 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
14722 1, string_sec->sh_size,
14723 _("string table"));
14724 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
14727 uint64_t si;
14729 for (si = 0; si < num_syms; si++)
14730 print_symbol (filedata, si, symtab, section, strtab, strtab_size);
14732 free (symtab);
14734 if (strtab != filedata->string_table)
14735 free (strtab);
14737 return true;
14740 /* Dump the symbol table. */
14742 static bool
14743 process_symbol_table (Filedata * filedata)
14745 Elf_Internal_Shdr * section;
14747 if (!do_syms && !do_dyn_syms && !do_histogram)
14748 return true;
14750 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
14751 && do_syms
14752 && do_using_dynamic
14753 && filedata->dynamic_strings != NULL
14754 && filedata->dynamic_symbols != NULL)
14756 uint64_t si;
14758 if (filedata->is_separate)
14760 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table"
14761 " contains %" PRIu64 " entry:\n",
14762 "\nIn linked file '%s' the dynamic symbol table"
14763 " contains %" PRIu64 " entries:\n",
14764 filedata->num_dynamic_syms),
14765 filedata->file_name,
14766 filedata->num_dynamic_syms);
14768 else
14770 printf (ngettext ("\nSymbol table for image contains %" PRIu64
14771 " entry:\n",
14772 "\nSymbol table for image contains %" PRIu64
14773 " entries:\n",
14774 filedata->num_dynamic_syms),
14775 filedata->num_dynamic_syms);
14778 print_symbol_table_heading ();
14780 for (si = 0; si < filedata->num_dynamic_syms; si++)
14781 print_symbol (filedata, si, filedata->dynamic_symbols, NULL,
14782 filedata->dynamic_strings,
14783 filedata->dynamic_strings_length);
14785 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
14786 && filedata->section_headers != NULL)
14788 unsigned int i;
14790 for (i = 0, section = filedata->section_headers;
14791 i < filedata->file_header.e_shnum;
14792 i++, section++)
14794 if ((section->sh_type != SHT_SYMTAB
14795 && section->sh_type != SHT_DYNSYM)
14796 || (!do_syms
14797 && section->sh_type == SHT_SYMTAB))
14798 continue;
14800 dump_symbol_section (section, filedata);
14803 else if (do_syms)
14804 printf
14805 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
14807 if (do_histogram && filedata->buckets != NULL)
14809 uint64_t *lengths;
14810 uint64_t *counts;
14811 uint64_t hn;
14812 uint64_t si;
14813 uint64_t maxlength = 0;
14814 uint64_t nzero_counts = 0;
14815 uint64_t nsyms = 0;
14816 char *visited;
14818 printf (ngettext ("\nHistogram for bucket list length "
14819 "(total of %" PRIu64 " bucket):\n",
14820 "\nHistogram for bucket list length "
14821 "(total of %" PRIu64 " buckets):\n",
14822 filedata->nbuckets),
14823 filedata->nbuckets);
14825 lengths = calloc (filedata->nbuckets, sizeof (*lengths));
14826 if (lengths == NULL)
14828 error (_("Out of memory allocating space for histogram buckets\n"));
14829 goto err_out;
14831 visited = xcmalloc (filedata->nchains, 1);
14832 memset (visited, 0, filedata->nchains);
14834 printf (_(" Length Number %% of total Coverage\n"));
14835 for (hn = 0; hn < filedata->nbuckets; ++hn)
14837 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
14839 ++nsyms;
14840 if (maxlength < ++lengths[hn])
14841 ++maxlength;
14842 if (si >= filedata->nchains || visited[si])
14844 error (_("histogram chain is corrupt\n"));
14845 break;
14847 visited[si] = 1;
14850 free (visited);
14852 counts = calloc (maxlength + 1, sizeof (*counts));
14853 if (counts == NULL)
14855 free (lengths);
14856 error (_("Out of memory allocating space for histogram counts\n"));
14857 goto err_out;
14860 for (hn = 0; hn < filedata->nbuckets; ++hn)
14861 ++counts[lengths[hn]];
14863 if (filedata->nbuckets > 0)
14865 uint64_t i;
14866 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
14867 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
14868 for (i = 1; i <= maxlength; ++i)
14870 nzero_counts += counts[i] * i;
14871 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
14872 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
14873 (nzero_counts * 100.0) / nsyms);
14877 free (counts);
14878 free (lengths);
14881 free (filedata->buckets);
14882 filedata->buckets = NULL;
14883 filedata->nbuckets = 0;
14884 free (filedata->chains);
14885 filedata->chains = NULL;
14887 if (do_histogram && filedata->gnubuckets != NULL)
14889 uint64_t *lengths;
14890 uint64_t *counts;
14891 uint64_t hn;
14892 uint64_t maxlength = 0;
14893 uint64_t nzero_counts = 0;
14894 uint64_t nsyms = 0;
14896 printf (ngettext ("\nHistogram for `%s' bucket list length "
14897 "(total of %" PRIu64 " bucket):\n",
14898 "\nHistogram for `%s' bucket list length "
14899 "(total of %" PRIu64 " buckets):\n",
14900 filedata->ngnubuckets),
14901 GNU_HASH_SECTION_NAME (filedata),
14902 filedata->ngnubuckets);
14904 lengths = calloc (filedata->ngnubuckets, sizeof (*lengths));
14905 if (lengths == NULL)
14907 error (_("Out of memory allocating space for gnu histogram buckets\n"));
14908 goto err_out;
14911 printf (_(" Length Number %% of total Coverage\n"));
14913 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
14914 if (filedata->gnubuckets[hn] != 0)
14916 uint64_t off, length = 1;
14918 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
14919 /* PR 17531 file: 010-77222-0.004. */
14920 off < filedata->ngnuchains
14921 && (filedata->gnuchains[off] & 1) == 0;
14922 ++off)
14923 ++length;
14924 lengths[hn] = length;
14925 if (length > maxlength)
14926 maxlength = length;
14927 nsyms += length;
14930 counts = calloc (maxlength + 1, sizeof (*counts));
14931 if (counts == NULL)
14933 free (lengths);
14934 error (_("Out of memory allocating space for gnu histogram counts\n"));
14935 goto err_out;
14938 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
14939 ++counts[lengths[hn]];
14941 if (filedata->ngnubuckets > 0)
14943 uint64_t j;
14944 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
14945 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
14946 for (j = 1; j <= maxlength; ++j)
14948 nzero_counts += counts[j] * j;
14949 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
14950 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
14951 (nzero_counts * 100.0) / nsyms);
14955 free (counts);
14956 free (lengths);
14958 free (filedata->gnubuckets);
14959 filedata->gnubuckets = NULL;
14960 filedata->ngnubuckets = 0;
14961 free (filedata->gnuchains);
14962 filedata->gnuchains = NULL;
14963 filedata->ngnuchains = 0;
14964 free (filedata->mipsxlat);
14965 filedata->mipsxlat = NULL;
14966 return true;
14968 err_out:
14969 free (filedata->gnubuckets);
14970 filedata->gnubuckets = NULL;
14971 filedata->ngnubuckets = 0;
14972 free (filedata->gnuchains);
14973 filedata->gnuchains = NULL;
14974 filedata->ngnuchains = 0;
14975 free (filedata->mipsxlat);
14976 filedata->mipsxlat = NULL;
14977 free (filedata->buckets);
14978 filedata->buckets = NULL;
14979 filedata->nbuckets = 0;
14980 free (filedata->chains);
14981 filedata->chains = NULL;
14982 return false;
14985 static bool
14986 process_syminfo (Filedata * filedata)
14988 unsigned int i;
14990 if (filedata->dynamic_syminfo == NULL
14991 || !do_dynamic)
14992 /* No syminfo, this is ok. */
14993 return true;
14995 /* There better should be a dynamic symbol section. */
14996 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
14997 return false;
14999 if (filedata->is_separate)
15000 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entry:\n",
15001 "\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entries:\n",
15002 filedata->dynamic_syminfo_nent),
15003 filedata->file_name,
15004 filedata->dynamic_syminfo_offset,
15005 filedata->dynamic_syminfo_nent);
15006 else
15007 printf (ngettext ("\nDynamic info segment at offset %#" PRIx64
15008 " contains %d entry:\n",
15009 "\nDynamic info segment at offset %#" PRIx64
15010 " contains %d entries:\n",
15011 filedata->dynamic_syminfo_nent),
15012 filedata->dynamic_syminfo_offset,
15013 filedata->dynamic_syminfo_nent);
15015 printf (_(" Num: Name BoundTo Flags\n"));
15016 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
15018 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
15020 printf ("%4d: ", i);
15021 if (i >= filedata->num_dynamic_syms)
15022 printf (_("<corrupt index>"));
15023 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
15024 print_symbol_name (30, get_dynamic_name (filedata,
15025 filedata->dynamic_symbols[i].st_name));
15026 else
15027 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
15028 putchar (' ');
15030 switch (filedata->dynamic_syminfo[i].si_boundto)
15032 case SYMINFO_BT_SELF:
15033 fputs ("SELF ", stdout);
15034 break;
15035 case SYMINFO_BT_PARENT:
15036 fputs ("PARENT ", stdout);
15037 break;
15038 default:
15039 if (filedata->dynamic_syminfo[i].si_boundto > 0
15040 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
15041 && valid_dynamic_name (filedata,
15042 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
15044 print_symbol_name (10, get_dynamic_name (filedata,
15045 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
15046 putchar (' ' );
15048 else
15049 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
15050 break;
15053 if (flags & SYMINFO_FLG_DIRECT)
15054 printf (" DIRECT");
15055 if (flags & SYMINFO_FLG_PASSTHRU)
15056 printf (" PASSTHRU");
15057 if (flags & SYMINFO_FLG_COPY)
15058 printf (" COPY");
15059 if (flags & SYMINFO_FLG_LAZYLOAD)
15060 printf (" LAZYLOAD");
15062 puts ("");
15065 return true;
15068 /* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
15069 is contained by the region START .. END. The types of ADDR, START
15070 and END should all be the same. Note both ADDR + NELEM and END
15071 point to just beyond the end of the regions that are being tested. */
15072 #define IN_RANGE(START,END,ADDR,NELEM) \
15073 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
15075 /* Check to see if the given reloc needs to be handled in a target specific
15076 manner. If so then process the reloc and return TRUE otherwise return
15077 FALSE.
15079 If called with reloc == NULL, then this is a signal that reloc processing
15080 for the current section has finished, and any saved state should be
15081 discarded. */
15083 static bool
15084 target_specific_reloc_handling (Filedata *filedata,
15085 Elf_Internal_Rela *reloc,
15086 unsigned char *start,
15087 unsigned char *end,
15088 Elf_Internal_Sym *symtab,
15089 uint64_t num_syms)
15091 unsigned int reloc_type = 0;
15092 uint64_t sym_index = 0;
15094 if (reloc)
15096 reloc_type = get_reloc_type (filedata, reloc->r_info);
15097 sym_index = get_reloc_symindex (reloc->r_info);
15100 switch (filedata->file_header.e_machine)
15102 case EM_LOONGARCH:
15104 switch (reloc_type)
15106 /* For .uleb128 .LFE1-.LFB1, loongarch write 0 to object file
15107 at assembly time. */
15108 case 107: /* R_LARCH_ADD_ULEB128. */
15109 case 108: /* R_LARCH_SUB_ULEB128. */
15111 uint64_t value = 0;
15112 unsigned int reloc_size = 0;
15113 int leb_ret = 0;
15115 if (reloc->r_offset < (size_t) (end - start))
15116 value = read_leb128 (start + reloc->r_offset, end, false,
15117 &reloc_size, &leb_ret);
15118 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
15119 error (_("LoongArch ULEB128 field at 0x%lx contains invalid "
15120 "ULEB128 value\n"),
15121 (long) reloc->r_offset);
15123 else if (sym_index >= num_syms)
15124 error (_("%s reloc contains invalid symbol index "
15125 "%" PRIu64 "\n"),
15126 (reloc_type == 107
15127 ? "R_LARCH_ADD_ULEB128"
15128 : "R_LARCH_SUB_ULEB128"),
15129 sym_index);
15130 else
15132 if (reloc_type == 107)
15133 value += reloc->r_addend + symtab[sym_index].st_value;
15134 else
15135 value -= reloc->r_addend + symtab[sym_index].st_value;
15137 /* Write uleb128 value to p. */
15138 bfd_byte *p = start + reloc->r_offset;
15141 bfd_byte c = value & 0x7f;
15142 value >>= 7;
15143 if (--reloc_size != 0)
15144 c |= 0x80;
15145 *p++ = c;
15147 while (reloc_size);
15150 return true;
15153 break;
15156 case EM_MSP430:
15157 case EM_MSP430_OLD:
15159 static Elf_Internal_Sym * saved_sym = NULL;
15161 if (reloc == NULL)
15163 saved_sym = NULL;
15164 return true;
15167 switch (reloc_type)
15169 case 10: /* R_MSP430_SYM_DIFF */
15170 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
15171 if (uses_msp430x_relocs (filedata))
15172 break;
15173 /* Fall through. */
15174 case 21: /* R_MSP430X_SYM_DIFF */
15175 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
15176 /* PR 21139. */
15177 if (sym_index >= num_syms)
15178 error (_("%s reloc contains invalid symbol index "
15179 "%" PRIu64 "\n"), "MSP430 SYM_DIFF", sym_index);
15180 else
15181 saved_sym = symtab + sym_index;
15182 return true;
15184 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
15185 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
15186 goto handle_sym_diff;
15188 case 5: /* R_MSP430_16_BYTE */
15189 case 9: /* R_MSP430_8 */
15190 case 11: /* R_MSP430_GNU_SET_ULEB128 */
15191 if (uses_msp430x_relocs (filedata))
15192 break;
15193 goto handle_sym_diff;
15195 case 2: /* R_MSP430_ABS16 */
15196 case 15: /* R_MSP430X_ABS16 */
15197 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
15198 if (! uses_msp430x_relocs (filedata))
15199 break;
15200 goto handle_sym_diff;
15202 handle_sym_diff:
15203 if (saved_sym != NULL)
15205 uint64_t value;
15206 unsigned int reloc_size = 0;
15207 int leb_ret = 0;
15208 switch (reloc_type)
15210 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
15211 reloc_size = 4;
15212 break;
15213 case 11: /* R_MSP430_GNU_SET_ULEB128 */
15214 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
15215 if (reloc->r_offset < (size_t) (end - start))
15216 read_leb128 (start + reloc->r_offset, end, false,
15217 &reloc_size, &leb_ret);
15218 break;
15219 default:
15220 reloc_size = 2;
15221 break;
15224 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
15225 error (_("MSP430 ULEB128 field at %#" PRIx64
15226 " contains invalid ULEB128 value\n"),
15227 reloc->r_offset);
15228 else if (sym_index >= num_syms)
15229 error (_("%s reloc contains invalid symbol index "
15230 "%" PRIu64 "\n"), "MSP430", sym_index);
15231 else
15233 value = reloc->r_addend + (symtab[sym_index].st_value
15234 - saved_sym->st_value);
15236 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
15237 byte_put (start + reloc->r_offset, value, reloc_size);
15238 else
15239 /* PR 21137 */
15240 error (_("MSP430 sym diff reloc contains invalid offset: "
15241 "%#" PRIx64 "\n"),
15242 reloc->r_offset);
15245 saved_sym = NULL;
15246 return true;
15248 break;
15250 default:
15251 if (saved_sym != NULL)
15252 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
15253 break;
15255 break;
15258 case EM_MN10300:
15259 case EM_CYGNUS_MN10300:
15261 static Elf_Internal_Sym * saved_sym = NULL;
15263 if (reloc == NULL)
15265 saved_sym = NULL;
15266 return true;
15269 switch (reloc_type)
15271 case 34: /* R_MN10300_ALIGN */
15272 return true;
15273 case 33: /* R_MN10300_SYM_DIFF */
15274 if (sym_index >= num_syms)
15275 error (_("%s reloc contains invalid symbol index "
15276 "%" PRIu64 "\n"), "MN10300_SYM_DIFF", sym_index);
15277 else
15278 saved_sym = symtab + sym_index;
15279 return true;
15281 case 1: /* R_MN10300_32 */
15282 case 2: /* R_MN10300_16 */
15283 if (saved_sym != NULL)
15285 int reloc_size = reloc_type == 1 ? 4 : 2;
15286 uint64_t value;
15288 if (sym_index >= num_syms)
15289 error (_("%s reloc contains invalid symbol index "
15290 "%" PRIu64 "\n"), "MN10300", sym_index);
15291 else
15293 value = reloc->r_addend + (symtab[sym_index].st_value
15294 - saved_sym->st_value);
15296 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
15297 byte_put (start + reloc->r_offset, value, reloc_size);
15298 else
15299 error (_("MN10300 sym diff reloc contains invalid offset:"
15300 " %#" PRIx64 "\n"),
15301 reloc->r_offset);
15304 saved_sym = NULL;
15305 return true;
15307 break;
15308 default:
15309 if (saved_sym != NULL)
15310 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
15311 break;
15313 break;
15316 case EM_RL78:
15318 static uint64_t saved_sym1 = 0;
15319 static uint64_t saved_sym2 = 0;
15320 static uint64_t value;
15322 if (reloc == NULL)
15324 saved_sym1 = saved_sym2 = 0;
15325 return true;
15328 switch (reloc_type)
15330 case 0x80: /* R_RL78_SYM. */
15331 saved_sym1 = saved_sym2;
15332 if (sym_index >= num_syms)
15333 error (_("%s reloc contains invalid symbol index "
15334 "%" PRIu64 "\n"), "RL78_SYM", sym_index);
15335 else
15337 saved_sym2 = symtab[sym_index].st_value;
15338 saved_sym2 += reloc->r_addend;
15340 return true;
15342 case 0x83: /* R_RL78_OPsub. */
15343 value = saved_sym1 - saved_sym2;
15344 saved_sym2 = saved_sym1 = 0;
15345 return true;
15346 break;
15348 case 0x41: /* R_RL78_ABS32. */
15349 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
15350 byte_put (start + reloc->r_offset, value, 4);
15351 else
15352 error (_("RL78 sym diff reloc contains invalid offset: "
15353 "%#" PRIx64 "\n"),
15354 reloc->r_offset);
15355 value = 0;
15356 return true;
15358 case 0x43: /* R_RL78_ABS16. */
15359 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
15360 byte_put (start + reloc->r_offset, value, 2);
15361 else
15362 error (_("RL78 sym diff reloc contains invalid offset: "
15363 "%#" PRIx64 "\n"),
15364 reloc->r_offset);
15365 value = 0;
15366 return true;
15368 default:
15369 break;
15371 break;
15375 return false;
15378 /* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
15379 DWARF debug sections. This is a target specific test. Note - we do not
15380 go through the whole including-target-headers-multiple-times route, (as
15381 we have already done with <elf/h8.h>) because this would become very
15382 messy and even then this function would have to contain target specific
15383 information (the names of the relocs instead of their numeric values).
15384 FIXME: This is not the correct way to solve this problem. The proper way
15385 is to have target specific reloc sizing and typing functions created by
15386 the reloc-macros.h header, in the same way that it already creates the
15387 reloc naming functions. */
15389 static bool
15390 is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15392 /* Please keep this table alpha-sorted for ease of visual lookup. */
15393 switch (filedata->file_header.e_machine)
15395 case EM_386:
15396 case EM_IAMCU:
15397 return reloc_type == 1; /* R_386_32. */
15398 case EM_68K:
15399 return reloc_type == 1; /* R_68K_32. */
15400 case EM_860:
15401 return reloc_type == 1; /* R_860_32. */
15402 case EM_960:
15403 return reloc_type == 2; /* R_960_32. */
15404 case EM_AARCH64:
15405 return (reloc_type == 258
15406 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
15407 case EM_BPF:
15408 return reloc_type == 11; /* R_BPF_DATA_32 */
15409 case EM_ADAPTEVA_EPIPHANY:
15410 return reloc_type == 3;
15411 case EM_ALPHA:
15412 return reloc_type == 1; /* R_ALPHA_REFLONG. */
15413 case EM_ARC:
15414 return reloc_type == 1; /* R_ARC_32. */
15415 case EM_ARC_COMPACT:
15416 case EM_ARC_COMPACT2:
15417 case EM_ARC_COMPACT3:
15418 case EM_ARC_COMPACT3_64:
15419 return reloc_type == 4; /* R_ARC_32. */
15420 case EM_ARM:
15421 return reloc_type == 2; /* R_ARM_ABS32 */
15422 case EM_AVR_OLD:
15423 case EM_AVR:
15424 return reloc_type == 1;
15425 case EM_BLACKFIN:
15426 return reloc_type == 0x12; /* R_byte4_data. */
15427 case EM_CRIS:
15428 return reloc_type == 3; /* R_CRIS_32. */
15429 case EM_CR16:
15430 return reloc_type == 3; /* R_CR16_NUM32. */
15431 case EM_CRX:
15432 return reloc_type == 15; /* R_CRX_NUM32. */
15433 case EM_CSKY:
15434 return reloc_type == 1; /* R_CKCORE_ADDR32. */
15435 case EM_CYGNUS_FRV:
15436 return reloc_type == 1;
15437 case EM_CYGNUS_D10V:
15438 case EM_D10V:
15439 return reloc_type == 6; /* R_D10V_32. */
15440 case EM_CYGNUS_D30V:
15441 case EM_D30V:
15442 return reloc_type == 12; /* R_D30V_32_NORMAL. */
15443 case EM_DLX:
15444 return reloc_type == 3; /* R_DLX_RELOC_32. */
15445 case EM_CYGNUS_FR30:
15446 case EM_FR30:
15447 return reloc_type == 3; /* R_FR30_32. */
15448 case EM_FT32:
15449 return reloc_type == 1; /* R_FT32_32. */
15450 case EM_H8S:
15451 case EM_H8_300:
15452 case EM_H8_300H:
15453 return reloc_type == 1; /* R_H8_DIR32. */
15454 case EM_IA_64:
15455 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
15456 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
15457 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
15458 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
15459 case EM_IP2K_OLD:
15460 case EM_IP2K:
15461 return reloc_type == 2; /* R_IP2K_32. */
15462 case EM_IQ2000:
15463 return reloc_type == 2; /* R_IQ2000_32. */
15464 case EM_KVX:
15465 return reloc_type == 2; /* R_KVX_32. */
15466 case EM_LATTICEMICO32:
15467 return reloc_type == 3; /* R_LM32_32. */
15468 case EM_LOONGARCH:
15469 return reloc_type == 1; /* R_LARCH_32. */
15470 case EM_M32C_OLD:
15471 case EM_M32C:
15472 return reloc_type == 3; /* R_M32C_32. */
15473 case EM_M32R:
15474 return reloc_type == 34; /* R_M32R_32_RELA. */
15475 case EM_68HC11:
15476 case EM_68HC12:
15477 return reloc_type == 6; /* R_M68HC11_32. */
15478 case EM_S12Z:
15479 return reloc_type == 7 || /* R_S12Z_EXT32 */
15480 reloc_type == 6; /* R_S12Z_CW32. */
15481 case EM_MCORE:
15482 return reloc_type == 1; /* R_MCORE_ADDR32. */
15483 case EM_CYGNUS_MEP:
15484 return reloc_type == 4; /* R_MEP_32. */
15485 case EM_METAG:
15486 return reloc_type == 2; /* R_METAG_ADDR32. */
15487 case EM_MICROBLAZE:
15488 return reloc_type == 1; /* R_MICROBLAZE_32. */
15489 case EM_MIPS:
15490 return reloc_type == 2; /* R_MIPS_32. */
15491 case EM_MMIX:
15492 return reloc_type == 4; /* R_MMIX_32. */
15493 case EM_CYGNUS_MN10200:
15494 case EM_MN10200:
15495 return reloc_type == 1; /* R_MN10200_32. */
15496 case EM_CYGNUS_MN10300:
15497 case EM_MN10300:
15498 return reloc_type == 1; /* R_MN10300_32. */
15499 case EM_MOXIE:
15500 return reloc_type == 1; /* R_MOXIE_32. */
15501 case EM_MSP430_OLD:
15502 case EM_MSP430:
15503 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
15504 case EM_MT:
15505 return reloc_type == 2; /* R_MT_32. */
15506 case EM_NDS32:
15507 return reloc_type == 20; /* R_NDS32_32_RELA. */
15508 case EM_ALTERA_NIOS2:
15509 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
15510 case EM_NIOS32:
15511 return reloc_type == 1; /* R_NIOS_32. */
15512 case EM_OR1K:
15513 return reloc_type == 1; /* R_OR1K_32. */
15514 case EM_PARISC:
15515 return (reloc_type == 1 /* R_PARISC_DIR32. */
15516 || reloc_type == 2 /* R_PARISC_DIR21L. */
15517 || reloc_type == 41); /* R_PARISC_SECREL32. */
15518 case EM_PJ:
15519 case EM_PJ_OLD:
15520 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
15521 case EM_PPC64:
15522 return reloc_type == 1; /* R_PPC64_ADDR32. */
15523 case EM_PPC:
15524 return reloc_type == 1; /* R_PPC_ADDR32. */
15525 case EM_TI_PRU:
15526 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
15527 case EM_RISCV:
15528 return reloc_type == 1; /* R_RISCV_32. */
15529 case EM_RL78:
15530 return reloc_type == 1; /* R_RL78_DIR32. */
15531 case EM_RX:
15532 return reloc_type == 1; /* R_RX_DIR32. */
15533 case EM_S370:
15534 return reloc_type == 1; /* R_I370_ADDR31. */
15535 case EM_S390_OLD:
15536 case EM_S390:
15537 return reloc_type == 4; /* R_S390_32. */
15538 case EM_SCORE:
15539 return reloc_type == 8; /* R_SCORE_ABS32. */
15540 case EM_SH:
15541 return reloc_type == 1; /* R_SH_DIR32. */
15542 case EM_SPARC32PLUS:
15543 case EM_SPARCV9:
15544 case EM_SPARC:
15545 return reloc_type == 3 /* R_SPARC_32. */
15546 || reloc_type == 23; /* R_SPARC_UA32. */
15547 case EM_SPU:
15548 return reloc_type == 6; /* R_SPU_ADDR32 */
15549 case EM_TI_C6000:
15550 return reloc_type == 1; /* R_C6000_ABS32. */
15551 case EM_TILEGX:
15552 return reloc_type == 2; /* R_TILEGX_32. */
15553 case EM_TILEPRO:
15554 return reloc_type == 1; /* R_TILEPRO_32. */
15555 case EM_CYGNUS_V850:
15556 case EM_V850:
15557 return reloc_type == 6; /* R_V850_ABS32. */
15558 case EM_V800:
15559 return reloc_type == 0x33; /* R_V810_WORD. */
15560 case EM_VAX:
15561 return reloc_type == 1; /* R_VAX_32. */
15562 case EM_VISIUM:
15563 return reloc_type == 3; /* R_VISIUM_32. */
15564 case EM_WEBASSEMBLY:
15565 return reloc_type == 1; /* R_WASM32_32. */
15566 case EM_X86_64:
15567 case EM_L1OM:
15568 case EM_K1OM:
15569 return reloc_type == 10; /* R_X86_64_32. */
15570 case EM_XGATE:
15571 return reloc_type == 4; /* R_XGATE_32. */
15572 case EM_XSTORMY16:
15573 return reloc_type == 1; /* R_XSTROMY16_32. */
15574 case EM_XTENSA_OLD:
15575 case EM_XTENSA:
15576 return reloc_type == 1; /* R_XTENSA_32. */
15577 case EM_Z80:
15578 return reloc_type == 6; /* R_Z80_32. */
15579 default:
15581 static unsigned int prev_warn = 0;
15583 /* Avoid repeating the same warning multiple times. */
15584 if (prev_warn != filedata->file_header.e_machine)
15585 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
15586 filedata->file_header.e_machine);
15587 prev_warn = filedata->file_header.e_machine;
15588 return false;
15593 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15594 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
15596 static bool
15597 is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
15599 switch (filedata->file_header.e_machine)
15600 /* Please keep this table alpha-sorted for ease of visual lookup. */
15602 case EM_386:
15603 case EM_IAMCU:
15604 return reloc_type == 2; /* R_386_PC32. */
15605 case EM_68K:
15606 return reloc_type == 4; /* R_68K_PC32. */
15607 case EM_AARCH64:
15608 return reloc_type == 261; /* R_AARCH64_PREL32 */
15609 case EM_ADAPTEVA_EPIPHANY:
15610 return reloc_type == 6;
15611 case EM_ALPHA:
15612 return reloc_type == 10; /* R_ALPHA_SREL32. */
15613 case EM_ARC_COMPACT:
15614 case EM_ARC_COMPACT2:
15615 case EM_ARC_COMPACT3:
15616 case EM_ARC_COMPACT3_64:
15617 return reloc_type == 49; /* R_ARC_32_PCREL. */
15618 case EM_ARM:
15619 return reloc_type == 3; /* R_ARM_REL32 */
15620 case EM_AVR_OLD:
15621 case EM_AVR:
15622 return reloc_type == 36; /* R_AVR_32_PCREL. */
15623 case EM_LOONGARCH:
15624 return reloc_type == 99; /* R_LARCH_32_PCREL. */
15625 case EM_MICROBLAZE:
15626 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
15627 case EM_OR1K:
15628 return reloc_type == 9; /* R_OR1K_32_PCREL. */
15629 case EM_PARISC:
15630 return reloc_type == 9; /* R_PARISC_PCREL32. */
15631 case EM_PPC:
15632 return reloc_type == 26; /* R_PPC_REL32. */
15633 case EM_PPC64:
15634 return reloc_type == 26; /* R_PPC64_REL32. */
15635 case EM_RISCV:
15636 return reloc_type == 57; /* R_RISCV_32_PCREL. */
15637 case EM_S390_OLD:
15638 case EM_S390:
15639 return reloc_type == 5; /* R_390_PC32. */
15640 case EM_SH:
15641 return reloc_type == 2; /* R_SH_REL32. */
15642 case EM_SPARC32PLUS:
15643 case EM_SPARCV9:
15644 case EM_SPARC:
15645 return reloc_type == 6; /* R_SPARC_DISP32. */
15646 case EM_SPU:
15647 return reloc_type == 13; /* R_SPU_REL32. */
15648 case EM_TILEGX:
15649 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
15650 case EM_TILEPRO:
15651 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
15652 case EM_VISIUM:
15653 return reloc_type == 6; /* R_VISIUM_32_PCREL */
15654 case EM_X86_64:
15655 case EM_L1OM:
15656 case EM_K1OM:
15657 return reloc_type == 2; /* R_X86_64_PC32. */
15658 case EM_VAX:
15659 return reloc_type == 4; /* R_VAX_PCREL32. */
15660 case EM_XTENSA_OLD:
15661 case EM_XTENSA:
15662 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
15663 case EM_KVX:
15664 return reloc_type == 7; /* R_KVX_32_PCREL */
15665 default:
15666 /* Do not abort or issue an error message here. Not all targets use
15667 pc-relative 32-bit relocs in their DWARF debug information and we
15668 have already tested for target coverage in is_32bit_abs_reloc. A
15669 more helpful warning message will be generated by apply_relocations
15670 anyway, so just return. */
15671 return false;
15675 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15676 a 64-bit absolute RELA relocation used in DWARF debug sections. */
15678 static bool
15679 is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15681 switch (filedata->file_header.e_machine)
15683 case EM_AARCH64:
15684 return reloc_type == 257; /* R_AARCH64_ABS64. */
15685 case EM_ARC_COMPACT3_64:
15686 return reloc_type == 5; /* R_ARC_64. */
15687 case EM_ALPHA:
15688 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
15689 case EM_IA_64:
15690 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
15691 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
15692 case EM_LOONGARCH:
15693 return reloc_type == 2; /* R_LARCH_64 */
15694 case EM_PARISC:
15695 return reloc_type == 80; /* R_PARISC_DIR64. */
15696 case EM_PPC64:
15697 return reloc_type == 38; /* R_PPC64_ADDR64. */
15698 case EM_RISCV:
15699 return reloc_type == 2; /* R_RISCV_64. */
15700 case EM_SPARC32PLUS:
15701 case EM_SPARCV9:
15702 case EM_SPARC:
15703 return reloc_type == 32 /* R_SPARC_64. */
15704 || reloc_type == 54; /* R_SPARC_UA64. */
15705 case EM_X86_64:
15706 case EM_L1OM:
15707 case EM_K1OM:
15708 return reloc_type == 1; /* R_X86_64_64. */
15709 case EM_S390_OLD:
15710 case EM_S390:
15711 return reloc_type == 22; /* R_S390_64. */
15712 case EM_TILEGX:
15713 return reloc_type == 1; /* R_TILEGX_64. */
15714 case EM_MIPS:
15715 return reloc_type == 18; /* R_MIPS_64. */
15716 case EM_KVX:
15717 return reloc_type == 3; /* R_KVX_64 */
15718 default:
15719 return false;
15723 /* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
15724 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
15726 static bool
15727 is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
15729 switch (filedata->file_header.e_machine)
15731 case EM_AARCH64:
15732 return reloc_type == 260; /* R_AARCH64_PREL64. */
15733 case EM_ALPHA:
15734 return reloc_type == 11; /* R_ALPHA_SREL64. */
15735 case EM_IA_64:
15736 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
15737 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
15738 case EM_PARISC:
15739 return reloc_type == 72; /* R_PARISC_PCREL64. */
15740 case EM_PPC64:
15741 return reloc_type == 44; /* R_PPC64_REL64. */
15742 case EM_SPARC32PLUS:
15743 case EM_SPARCV9:
15744 case EM_SPARC:
15745 return reloc_type == 46; /* R_SPARC_DISP64. */
15746 case EM_X86_64:
15747 case EM_L1OM:
15748 case EM_K1OM:
15749 return reloc_type == 24; /* R_X86_64_PC64. */
15750 case EM_S390_OLD:
15751 case EM_S390:
15752 return reloc_type == 23; /* R_S390_PC64. */
15753 case EM_TILEGX:
15754 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
15755 default:
15756 return false;
15760 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15761 a 24-bit absolute RELA relocation used in DWARF debug sections. */
15763 static bool
15764 is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15766 switch (filedata->file_header.e_machine)
15768 case EM_CYGNUS_MN10200:
15769 case EM_MN10200:
15770 return reloc_type == 4; /* R_MN10200_24. */
15771 case EM_FT32:
15772 return reloc_type == 5; /* R_FT32_20. */
15773 case EM_Z80:
15774 return reloc_type == 5; /* R_Z80_24. */
15775 default:
15776 return false;
15780 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15781 a 16-bit absolute RELA relocation used in DWARF debug sections. */
15783 static bool
15784 is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15786 /* Please keep this table alpha-sorted for ease of visual lookup. */
15787 switch (filedata->file_header.e_machine)
15789 case EM_ARC:
15790 case EM_ARC_COMPACT:
15791 case EM_ARC_COMPACT2:
15792 case EM_ARC_COMPACT3:
15793 case EM_ARC_COMPACT3_64:
15794 return reloc_type == 2; /* R_ARC_16. */
15795 case EM_ADAPTEVA_EPIPHANY:
15796 return reloc_type == 5;
15797 case EM_AVR_OLD:
15798 case EM_AVR:
15799 return reloc_type == 4; /* R_AVR_16. */
15800 case EM_CYGNUS_D10V:
15801 case EM_D10V:
15802 return reloc_type == 3; /* R_D10V_16. */
15803 case EM_FT32:
15804 return reloc_type == 2; /* R_FT32_16. */
15805 case EM_H8S:
15806 case EM_H8_300:
15807 case EM_H8_300H:
15808 return reloc_type == R_H8_DIR16;
15809 case EM_IP2K_OLD:
15810 case EM_IP2K:
15811 return reloc_type == 1; /* R_IP2K_16. */
15812 case EM_M32C_OLD:
15813 case EM_M32C:
15814 return reloc_type == 1; /* R_M32C_16 */
15815 case EM_CYGNUS_MN10200:
15816 case EM_MN10200:
15817 return reloc_type == 2; /* R_MN10200_16. */
15818 case EM_CYGNUS_MN10300:
15819 case EM_MN10300:
15820 return reloc_type == 2; /* R_MN10300_16. */
15821 case EM_KVX:
15822 return reloc_type == 1; /* R_KVX_16 */
15823 case EM_MSP430:
15824 if (uses_msp430x_relocs (filedata))
15825 return reloc_type == 2; /* R_MSP430_ABS16. */
15826 /* Fall through. */
15827 case EM_MSP430_OLD:
15828 return reloc_type == 5; /* R_MSP430_16_BYTE. */
15829 case EM_NDS32:
15830 return reloc_type == 19; /* R_NDS32_16_RELA. */
15831 case EM_ALTERA_NIOS2:
15832 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
15833 case EM_NIOS32:
15834 return reloc_type == 9; /* R_NIOS_16. */
15835 case EM_OR1K:
15836 return reloc_type == 2; /* R_OR1K_16. */
15837 case EM_RISCV:
15838 return reloc_type == 55; /* R_RISCV_SET16. */
15839 case EM_TI_PRU:
15840 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
15841 case EM_TI_C6000:
15842 return reloc_type == 2; /* R_C6000_ABS16. */
15843 case EM_VISIUM:
15844 return reloc_type == 2; /* R_VISIUM_16. */
15845 case EM_XGATE:
15846 return reloc_type == 3; /* R_XGATE_16. */
15847 case EM_Z80:
15848 return reloc_type == 4; /* R_Z80_16. */
15849 default:
15850 return false;
15854 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15855 a 8-bit absolute RELA relocation used in DWARF debug sections. */
15857 static bool
15858 is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15860 switch (filedata->file_header.e_machine)
15862 case EM_RISCV:
15863 return reloc_type == 54; /* R_RISCV_SET8. */
15864 case EM_Z80:
15865 return reloc_type == 1; /* R_Z80_8. */
15866 case EM_MICROBLAZE:
15867 return (reloc_type == 33 /* R_MICROBLAZE_32_NONE. */
15868 || reloc_type == 0 /* R_MICROBLAZE_NONE. */
15869 || reloc_type == 9 /* R_MICROBLAZE_64_NONE. */);
15870 default:
15871 return false;
15875 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15876 a 6-bit absolute RELA relocation used in DWARF debug sections. */
15878 static bool
15879 is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15881 switch (filedata->file_header.e_machine)
15883 case EM_RISCV:
15884 return reloc_type == 53; /* R_RISCV_SET6. */
15885 default:
15886 return false;
15890 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15891 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
15893 static bool
15894 is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15896 /* Please keep this table alpha-sorted for ease of visual lookup. */
15897 switch (filedata->file_header.e_machine)
15899 case EM_LOONGARCH:
15900 return reloc_type == 50; /* R_LARCH_ADD32. */
15901 case EM_RISCV:
15902 return reloc_type == 35; /* R_RISCV_ADD32. */
15903 default:
15904 return false;
15908 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15909 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
15911 static bool
15912 is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15914 /* Please keep this table alpha-sorted for ease of visual lookup. */
15915 switch (filedata->file_header.e_machine)
15917 case EM_LOONGARCH:
15918 return reloc_type == 55; /* R_LARCH_SUB32. */
15919 case EM_RISCV:
15920 return reloc_type == 39; /* R_RISCV_SUB32. */
15921 default:
15922 return false;
15926 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15927 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
15929 static bool
15930 is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15932 /* Please keep this table alpha-sorted for ease of visual lookup. */
15933 switch (filedata->file_header.e_machine)
15935 case EM_LOONGARCH:
15936 return reloc_type == 51; /* R_LARCH_ADD64. */
15937 case EM_RISCV:
15938 return reloc_type == 36; /* R_RISCV_ADD64. */
15939 default:
15940 return false;
15944 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15945 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
15947 static bool
15948 is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15950 /* Please keep this table alpha-sorted for ease of visual lookup. */
15951 switch (filedata->file_header.e_machine)
15953 case EM_LOONGARCH:
15954 return reloc_type == 56; /* R_LARCH_SUB64. */
15955 case EM_RISCV:
15956 return reloc_type == 40; /* R_RISCV_SUB64. */
15957 default:
15958 return false;
15962 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15963 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
15965 static bool
15966 is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15968 /* Please keep this table alpha-sorted for ease of visual lookup. */
15969 switch (filedata->file_header.e_machine)
15971 case EM_LOONGARCH:
15972 return reloc_type == 48; /* R_LARCH_ADD16. */
15973 case EM_RISCV:
15974 return reloc_type == 34; /* R_RISCV_ADD16. */
15975 default:
15976 return false;
15980 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15981 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
15983 static bool
15984 is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15986 /* Please keep this table alpha-sorted for ease of visual lookup. */
15987 switch (filedata->file_header.e_machine)
15989 case EM_LOONGARCH:
15990 return reloc_type == 53; /* R_LARCH_SUB16. */
15991 case EM_RISCV:
15992 return reloc_type == 38; /* R_RISCV_SUB16. */
15993 default:
15994 return false;
15998 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15999 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
16001 static bool
16002 is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
16004 /* Please keep this table alpha-sorted for ease of visual lookup. */
16005 switch (filedata->file_header.e_machine)
16007 case EM_LOONGARCH:
16008 return reloc_type == 47; /* R_LARCH_ADD8. */
16009 case EM_RISCV:
16010 return reloc_type == 33; /* R_RISCV_ADD8. */
16011 default:
16012 return false;
16016 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
16017 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
16019 static bool
16020 is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
16022 /* Please keep this table alpha-sorted for ease of visual lookup. */
16023 switch (filedata->file_header.e_machine)
16025 case EM_LOONGARCH:
16026 return reloc_type == 52; /* R_LARCH_SUB8. */
16027 case EM_RISCV:
16028 return reloc_type == 37; /* R_RISCV_SUB8. */
16029 default:
16030 return false;
16034 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
16035 a 6-bit inplace add RELA relocation used in DWARF debug sections. */
16037 static bool
16038 is_6bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
16040 switch (filedata->file_header.e_machine)
16042 case EM_LOONGARCH:
16043 return reloc_type == 105; /* R_LARCH_ADD6. */
16044 default:
16045 return false;
16049 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
16050 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
16052 static bool
16053 is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
16055 switch (filedata->file_header.e_machine)
16057 case EM_LOONGARCH:
16058 return reloc_type == 106; /* R_LARCH_SUB6. */
16059 case EM_RISCV:
16060 return reloc_type == 52; /* R_RISCV_SUB6. */
16061 default:
16062 return false;
16066 /* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
16067 relocation entries (possibly formerly used for SHT_GROUP sections). */
16069 static bool
16070 is_none_reloc (Filedata * filedata, unsigned int reloc_type)
16072 switch (filedata->file_header.e_machine)
16074 case EM_386: /* R_386_NONE. */
16075 case EM_68K: /* R_68K_NONE. */
16076 case EM_ADAPTEVA_EPIPHANY:
16077 case EM_ALPHA: /* R_ALPHA_NONE. */
16078 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
16079 case EM_ARC: /* R_ARC_NONE. */
16080 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
16081 case EM_ARC_COMPACT: /* R_ARC_NONE. */
16082 case EM_ARC_COMPACT3: /* R_ARC_NONE. */
16083 case EM_ARC_COMPACT3_64: /* R_ARC_NONE. */
16084 case EM_ARM: /* R_ARM_NONE. */
16085 case EM_CRIS: /* R_CRIS_NONE. */
16086 case EM_FT32: /* R_FT32_NONE. */
16087 case EM_IA_64: /* R_IA64_NONE. */
16088 case EM_K1OM: /* R_X86_64_NONE. */
16089 case EM_KVX: /* R_KVX_NONE. */
16090 case EM_L1OM: /* R_X86_64_NONE. */
16091 case EM_M32R: /* R_M32R_NONE. */
16092 case EM_MIPS: /* R_MIPS_NONE. */
16093 case EM_MN10300: /* R_MN10300_NONE. */
16094 case EM_MOXIE: /* R_MOXIE_NONE. */
16095 case EM_NIOS32: /* R_NIOS_NONE. */
16096 case EM_OR1K: /* R_OR1K_NONE. */
16097 case EM_PARISC: /* R_PARISC_NONE. */
16098 case EM_PPC64: /* R_PPC64_NONE. */
16099 case EM_PPC: /* R_PPC_NONE. */
16100 case EM_RISCV: /* R_RISCV_NONE. */
16101 case EM_S390: /* R_390_NONE. */
16102 case EM_S390_OLD:
16103 case EM_SH: /* R_SH_NONE. */
16104 case EM_SPARC32PLUS:
16105 case EM_SPARC: /* R_SPARC_NONE. */
16106 case EM_SPARCV9:
16107 case EM_TILEGX: /* R_TILEGX_NONE. */
16108 case EM_TILEPRO: /* R_TILEPRO_NONE. */
16109 case EM_TI_C6000:/* R_C6000_NONE. */
16110 case EM_X86_64: /* R_X86_64_NONE. */
16111 case EM_Z80: /* R_Z80_NONE. */
16112 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
16113 return reloc_type == 0;
16115 case EM_AARCH64:
16116 return reloc_type == 0 || reloc_type == 256;
16117 case EM_AVR_OLD:
16118 case EM_AVR:
16119 return (reloc_type == 0 /* R_AVR_NONE. */
16120 || reloc_type == 30 /* R_AVR_DIFF8. */
16121 || reloc_type == 31 /* R_AVR_DIFF16. */
16122 || reloc_type == 32 /* R_AVR_DIFF32. */);
16123 case EM_METAG:
16124 return reloc_type == 3; /* R_METAG_NONE. */
16125 case EM_NDS32:
16126 return (reloc_type == 0 /* R_NDS32_NONE. */
16127 || reloc_type == 205 /* R_NDS32_DIFF8. */
16128 || reloc_type == 206 /* R_NDS32_DIFF16. */
16129 || reloc_type == 207 /* R_NDS32_DIFF32. */
16130 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
16131 case EM_TI_PRU:
16132 return (reloc_type == 0 /* R_PRU_NONE. */
16133 || reloc_type == 65 /* R_PRU_DIFF8. */
16134 || reloc_type == 66 /* R_PRU_DIFF16. */
16135 || reloc_type == 67 /* R_PRU_DIFF32. */);
16136 case EM_XTENSA_OLD:
16137 case EM_XTENSA:
16138 return (reloc_type == 0 /* R_XTENSA_NONE. */
16139 || reloc_type == 17 /* R_XTENSA_DIFF8. */
16140 || reloc_type == 18 /* R_XTENSA_DIFF16. */
16141 || reloc_type == 19 /* R_XTENSA_DIFF32. */
16142 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
16143 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
16144 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
16145 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
16146 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
16147 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
16149 return false;
16152 /* Returns TRUE if there is a relocation against
16153 section NAME at OFFSET bytes. */
16155 bool
16156 reloc_at (struct dwarf_section * dsec, uint64_t offset)
16158 Elf_Internal_Rela * relocs;
16159 Elf_Internal_Rela * rp;
16161 if (dsec == NULL || dsec->reloc_info == NULL)
16162 return false;
16164 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
16166 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
16167 if (rp->r_offset == offset)
16168 return true;
16170 return false;
16173 /* Apply relocations to a section.
16174 Returns TRUE upon success, FALSE otherwise.
16175 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
16176 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
16177 will be set to the number of relocs loaded.
16179 Note: So far support has been added only for those relocations
16180 which can be found in debug sections. FIXME: Add support for
16181 more relocations ? */
16183 static bool
16184 apply_relocations (Filedata *filedata,
16185 const Elf_Internal_Shdr *section,
16186 unsigned char *start,
16187 size_t size,
16188 void **relocs_return,
16189 uint64_t *num_relocs_return)
16191 Elf_Internal_Shdr * relsec;
16192 unsigned char * end = start + size;
16194 if (relocs_return != NULL)
16196 * (Elf_Internal_Rela **) relocs_return = NULL;
16197 * num_relocs_return = 0;
16200 if (filedata->file_header.e_type != ET_REL)
16201 /* No relocs to apply. */
16202 return true;
16204 /* Find the reloc section associated with the section. */
16205 for (relsec = filedata->section_headers;
16206 relsec < filedata->section_headers + filedata->file_header.e_shnum;
16207 ++relsec)
16209 bool is_rela;
16210 uint64_t num_relocs;
16211 Elf_Internal_Rela * relocs;
16212 Elf_Internal_Rela * rp;
16213 Elf_Internal_Shdr * symsec;
16214 Elf_Internal_Sym * symtab;
16215 uint64_t num_syms;
16216 Elf_Internal_Sym * sym;
16218 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
16219 || relsec->sh_info >= filedata->file_header.e_shnum
16220 || filedata->section_headers + relsec->sh_info != section
16221 || relsec->sh_size == 0
16222 || relsec->sh_link >= filedata->file_header.e_shnum)
16223 continue;
16225 symsec = filedata->section_headers + relsec->sh_link;
16226 if (symsec->sh_type != SHT_SYMTAB
16227 && symsec->sh_type != SHT_DYNSYM)
16228 return false;
16230 is_rela = relsec->sh_type == SHT_RELA;
16232 if (is_rela)
16234 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
16235 relsec->sh_size, & relocs, & num_relocs))
16236 return false;
16238 else
16240 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
16241 relsec->sh_size, & relocs, & num_relocs))
16242 return false;
16245 /* SH uses RELA but uses in place value instead of the addend field. */
16246 if (filedata->file_header.e_machine == EM_SH)
16247 is_rela = false;
16249 symtab = get_elf_symbols (filedata, symsec, & num_syms);
16251 for (rp = relocs; rp < relocs + num_relocs; ++rp)
16253 uint64_t addend;
16254 unsigned int reloc_type;
16255 unsigned int reloc_size;
16256 bool reloc_inplace = false;
16257 bool reloc_subtract = false;
16258 unsigned char *rloc;
16259 uint64_t sym_index;
16261 reloc_type = get_reloc_type (filedata, rp->r_info);
16263 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
16264 continue;
16265 else if (is_none_reloc (filedata, reloc_type))
16266 continue;
16267 else if (is_32bit_abs_reloc (filedata, reloc_type)
16268 || is_32bit_pcrel_reloc (filedata, reloc_type))
16269 reloc_size = 4;
16270 else if (is_64bit_abs_reloc (filedata, reloc_type)
16271 || is_64bit_pcrel_reloc (filedata, reloc_type))
16272 reloc_size = 8;
16273 else if (is_24bit_abs_reloc (filedata, reloc_type))
16274 reloc_size = 3;
16275 else if (is_16bit_abs_reloc (filedata, reloc_type))
16276 reloc_size = 2;
16277 else if (is_8bit_abs_reloc (filedata, reloc_type)
16278 || is_6bit_abs_reloc (filedata, reloc_type))
16279 reloc_size = 1;
16280 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
16281 reloc_type))
16282 || is_32bit_inplace_add_reloc (filedata, reloc_type))
16284 reloc_size = 4;
16285 reloc_inplace = true;
16287 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
16288 reloc_type))
16289 || is_64bit_inplace_add_reloc (filedata, reloc_type))
16291 reloc_size = 8;
16292 reloc_inplace = true;
16294 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
16295 reloc_type))
16296 || is_16bit_inplace_add_reloc (filedata, reloc_type))
16298 reloc_size = 2;
16299 reloc_inplace = true;
16301 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
16302 reloc_type))
16303 || is_8bit_inplace_add_reloc (filedata, reloc_type))
16305 reloc_size = 1;
16306 reloc_inplace = true;
16308 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
16309 reloc_type))
16310 || is_6bit_inplace_add_reloc (filedata, reloc_type))
16312 reloc_size = 1;
16313 reloc_inplace = true;
16315 else
16317 static unsigned int prev_reloc = 0;
16319 if (reloc_type != prev_reloc)
16320 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
16321 reloc_type, printable_section_name (filedata, section));
16322 prev_reloc = reloc_type;
16323 continue;
16326 rloc = start + rp->r_offset;
16327 if (!IN_RANGE (start, end, rloc, reloc_size))
16329 warn (_("skipping invalid relocation offset %#" PRIx64
16330 " in section %s\n"),
16331 rp->r_offset,
16332 printable_section_name (filedata, section));
16333 continue;
16336 sym_index = get_reloc_symindex (rp->r_info);
16337 if (sym_index >= num_syms)
16339 warn (_("skipping invalid relocation symbol index %#" PRIx64
16340 " in section %s\n"),
16341 sym_index, printable_section_name (filedata, section));
16342 continue;
16344 sym = symtab + sym_index;
16346 /* If the reloc has a symbol associated with it,
16347 make sure that it is of an appropriate type.
16349 Relocations against symbols without type can happen.
16350 Gcc -feliminate-dwarf2-dups may generate symbols
16351 without type for debug info.
16353 Icc generates relocations against function symbols
16354 instead of local labels.
16356 Relocations against object symbols can happen, eg when
16357 referencing a global array. For an example of this see
16358 the _clz.o binary in libgcc.a. */
16359 if (sym != symtab
16360 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
16361 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
16363 warn (_("skipping unexpected symbol type %s in section %s relocation %tu\n"),
16364 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
16365 printable_section_name (filedata, relsec),
16366 rp - relocs);
16367 continue;
16370 addend = 0;
16371 if (is_rela)
16372 addend += rp->r_addend;
16373 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
16374 partial_inplace. */
16375 if (!is_rela
16376 || (filedata->file_header.e_machine == EM_XTENSA
16377 && reloc_type == 1)
16378 || ((filedata->file_header.e_machine == EM_PJ
16379 || filedata->file_header.e_machine == EM_PJ_OLD)
16380 && reloc_type == 1)
16381 || ((filedata->file_header.e_machine == EM_D30V
16382 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
16383 && reloc_type == 12)
16384 || reloc_inplace)
16386 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
16387 addend += byte_get (rloc, reloc_size) & 0x3f;
16388 else
16389 addend += byte_get (rloc, reloc_size);
16392 if (is_32bit_pcrel_reloc (filedata, reloc_type)
16393 || is_64bit_pcrel_reloc (filedata, reloc_type))
16395 /* On HPPA, all pc-relative relocations are biased by 8. */
16396 if (filedata->file_header.e_machine == EM_PARISC)
16397 addend -= 8;
16398 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
16399 reloc_size);
16401 else if (is_6bit_abs_reloc (filedata, reloc_type)
16402 || is_6bit_inplace_sub_reloc (filedata, reloc_type)
16403 || is_6bit_inplace_add_reloc (filedata, reloc_type))
16405 if (reloc_subtract)
16406 addend -= sym->st_value;
16407 else
16408 addend += sym->st_value;
16409 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
16410 byte_put (rloc, addend, reloc_size);
16412 else if (reloc_subtract)
16413 byte_put (rloc, addend - sym->st_value, reloc_size);
16414 else
16415 byte_put (rloc, addend + sym->st_value, reloc_size);
16418 free (symtab);
16419 /* Let the target specific reloc processing code know that
16420 we have finished with these relocs. */
16421 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
16423 if (relocs_return)
16425 * (Elf_Internal_Rela **) relocs_return = relocs;
16426 * num_relocs_return = num_relocs;
16428 else
16429 free (relocs);
16431 break;
16434 return true;
16437 #ifdef SUPPORT_DISASSEMBLY
16438 static bool
16439 disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
16441 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
16443 /* FIXME: XXX -- to be done --- XXX */
16445 return true;
16447 #endif
16449 /* Reads in the contents of SECTION from FILE, returning a pointer
16450 to a malloc'ed buffer or NULL if something went wrong. */
16452 static char *
16453 get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
16455 uint64_t num_bytes = section->sh_size;
16457 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
16459 printf (_("Section '%s' has no data to dump.\n"),
16460 printable_section_name (filedata, section));
16461 return NULL;
16464 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
16465 _("section contents"));
16468 /* Uncompresses a section that was compressed using zlib/zstd, in place. */
16470 static bool
16471 uncompress_section_contents (bool is_zstd,
16472 unsigned char ** buffer,
16473 uint64_t uncompressed_size,
16474 uint64_t * size,
16475 uint64_t file_size)
16477 uint64_t compressed_size = *size;
16478 unsigned char *compressed_buffer = *buffer;
16479 unsigned char *uncompressed_buffer = NULL;
16480 z_stream strm;
16481 int rc;
16483 /* Similar to bfd_section_size_insane() in the BFD library we expect an
16484 upper limit of ~10x compression. Any compression larger than that is
16485 thought to be due to fuzzing of the compression header. */
16486 if (uncompressed_size > file_size * 10)
16488 error (_("Uncompressed section size is suspiciously large: 0x%" PRIu64 "\n"),
16489 uncompressed_size);
16490 goto fail;
16493 uncompressed_buffer = xmalloc (uncompressed_size);
16495 if (is_zstd)
16497 #ifdef HAVE_ZSTD
16498 size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size,
16499 compressed_buffer, compressed_size);
16500 if (ZSTD_isError (ret))
16501 goto fail;
16502 #endif
16504 else
16506 /* It is possible the section consists of several compressed
16507 buffers concatenated together, so we uncompress in a loop. */
16508 /* PR 18313: The state field in the z_stream structure is supposed
16509 to be invisible to the user (ie us), but some compilers will
16510 still complain about it being used without initialisation. So
16511 we first zero the entire z_stream structure and then set the fields
16512 that we need. */
16513 memset (&strm, 0, sizeof strm);
16514 strm.avail_in = compressed_size;
16515 strm.next_in = (Bytef *)compressed_buffer;
16516 strm.avail_out = uncompressed_size;
16518 rc = inflateInit (&strm);
16519 while (strm.avail_in > 0)
16521 if (rc != Z_OK)
16522 break;
16523 strm.next_out = ((Bytef *)uncompressed_buffer
16524 + (uncompressed_size - strm.avail_out));
16525 rc = inflate (&strm, Z_FINISH);
16526 if (rc != Z_STREAM_END)
16527 break;
16528 rc = inflateReset (&strm);
16530 if (inflateEnd (&strm) != Z_OK || rc != Z_OK || strm.avail_out != 0)
16531 goto fail;
16534 *buffer = uncompressed_buffer;
16535 *size = uncompressed_size;
16536 return true;
16538 fail:
16539 free (uncompressed_buffer);
16540 /* Indicate decompression failure. */
16541 *buffer = NULL;
16542 return false;
16545 static uint64_t
16546 maybe_expand_or_relocate_section (Elf_Internal_Shdr * section,
16547 Filedata * filedata,
16548 unsigned char ** start_ptr,
16549 unsigned char ** decomp_buf,
16550 bool relocate)
16552 uint64_t section_size = section->sh_size;
16553 unsigned char * start = * start_ptr;
16555 if (decompress_dumps)
16557 uint64_t new_size = section_size;
16558 uint64_t uncompressed_size = 0;
16559 bool is_zstd = false;
16561 if ((section->sh_flags & SHF_COMPRESSED) != 0)
16563 Elf_Internal_Chdr chdr;
16564 unsigned int compression_header_size
16565 = get_compression_header (& chdr, start, section_size);
16567 if (compression_header_size == 0)
16568 /* An error message will have already been generated
16569 by get_compression_header. */
16570 return (uint64_t) -1;
16572 if (chdr.ch_type == ch_compress_zlib)
16574 #ifdef HAVE_ZSTD
16575 else if (chdr.ch_type == ch_compress_zstd)
16576 is_zstd = true;
16577 #endif
16578 else
16580 warn (_("section '%s' has unsupported compress type: %d\n"),
16581 printable_section_name (filedata, section), chdr.ch_type);
16582 return (uint64_t) -1;
16585 uncompressed_size = chdr.ch_size;
16586 start += compression_header_size;
16587 new_size -= compression_header_size;
16589 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
16591 /* Read the zlib header. In this case, it should be "ZLIB"
16592 followed by the uncompressed section size, 8 bytes in
16593 big-endian order. */
16594 uncompressed_size = start[4]; uncompressed_size <<= 8;
16595 uncompressed_size += start[5]; uncompressed_size <<= 8;
16596 uncompressed_size += start[6]; uncompressed_size <<= 8;
16597 uncompressed_size += start[7]; uncompressed_size <<= 8;
16598 uncompressed_size += start[8]; uncompressed_size <<= 8;
16599 uncompressed_size += start[9]; uncompressed_size <<= 8;
16600 uncompressed_size += start[10]; uncompressed_size <<= 8;
16601 uncompressed_size += start[11];
16602 start += 12;
16603 new_size -= 12;
16606 if (uncompressed_size)
16608 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
16609 &new_size, filedata->file_size))
16611 *decomp_buf = start;
16612 section_size = new_size;
16614 else
16616 error (_("Unable to decompress section %s\n"),
16617 printable_section_name (filedata, section));
16618 return (uint64_t) -1;
16621 else
16622 start = * start_ptr;
16624 else if (((section->sh_flags & SHF_COMPRESSED) != 0)
16625 || (section_size > 12 && streq ((char *) start, "ZLIB")))
16627 printf (_(" NOTE: This section is compressed, but its contents have NOT been expanded for this dump.\n"));
16630 if (relocate)
16632 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
16633 return (uint64_t) -1;
16635 else
16637 Elf_Internal_Shdr *relsec;
16639 /* If the section being dumped has relocations against it the user might
16640 be expecting these relocations to have been applied. Check for this
16641 case and issue a warning message in order to avoid confusion.
16642 FIXME: Maybe we ought to have an option that dumps a section with
16643 relocs applied ? */
16644 for (relsec = filedata->section_headers;
16645 relsec < filedata->section_headers + filedata->file_header.e_shnum;
16646 ++relsec)
16648 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
16649 || relsec->sh_info >= filedata->file_header.e_shnum
16650 || filedata->section_headers + relsec->sh_info != section
16651 || relsec->sh_size == 0
16652 || relsec->sh_link >= filedata->file_header.e_shnum)
16653 continue;
16655 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
16656 break;
16660 * start_ptr = start;
16661 return section_size;
16664 static bool
16665 dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
16667 uint64_t num_bytes;
16668 unsigned char *data;
16669 unsigned char *end;
16670 unsigned char *real_start;
16671 unsigned char *start;
16672 unsigned char *decomp_buf;
16673 bool some_strings_shown;
16675 real_start = start = (unsigned char *) get_section_contents (section, filedata);
16676 if (start == NULL)
16677 /* PR 21820: Do not fail if the section was empty. */
16678 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
16680 num_bytes = section->sh_size;
16682 if (filedata->is_separate)
16683 printf (_("\nString dump of section '%s' in linked file %s:\n"),
16684 printable_section_name (filedata, section),
16685 filedata->file_name);
16686 else
16687 printf (_("\nString dump of section '%s':\n"),
16688 printable_section_name (filedata, section));
16690 decomp_buf = NULL;
16691 num_bytes = maybe_expand_or_relocate_section (section, filedata, &start,
16692 &decomp_buf, false);
16693 if (num_bytes == (uint64_t) -1)
16694 goto error_out;
16696 data = start;
16697 end = start + num_bytes;
16698 some_strings_shown = false;
16700 #ifdef HAVE_MBSTATE_T
16701 mbstate_t state;
16702 /* Initialise the multibyte conversion state. */
16703 memset (& state, 0, sizeof (state));
16704 #endif
16706 bool continuing = false;
16708 while (data < end)
16710 while (!ISPRINT (* data))
16711 if (++ data >= end)
16712 break;
16714 if (data < end)
16716 size_t maxlen = end - data;
16718 if (continuing)
16720 printf (" ");
16721 continuing = false;
16723 else
16725 printf (" [%6tx] ", data - start);
16728 if (maxlen > 0)
16730 char c = 0;
16732 while (maxlen)
16734 c = *data++;
16736 if (c == 0)
16737 break;
16739 /* PR 25543: Treat new-lines as string-ending characters. */
16740 if (c == '\n')
16742 printf ("\\n\n");
16743 if (*data != 0)
16744 continuing = true;
16745 break;
16748 /* Do not print control characters directly as they can affect terminal
16749 settings. Such characters usually appear in the names generated
16750 by the assembler for local labels. */
16751 if (ISCNTRL (c))
16753 printf ("^%c", c + 0x40);
16755 else if (ISPRINT (c))
16757 putchar (c);
16759 else
16761 size_t n;
16762 #ifdef HAVE_MBSTATE_T
16763 wchar_t w;
16764 #endif
16765 /* Let printf do the hard work of displaying multibyte characters. */
16766 printf ("%.1s", data - 1);
16767 #ifdef HAVE_MBSTATE_T
16768 /* Try to find out how many bytes made up the character that was
16769 just printed. Advance the symbol pointer past the bytes that
16770 were displayed. */
16771 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
16772 #else
16773 n = 1;
16774 #endif
16775 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
16776 data += (n - 1);
16780 if (c != '\n')
16781 putchar ('\n');
16783 else
16785 printf (_("<corrupt>\n"));
16786 data = end;
16788 some_strings_shown = true;
16792 if (! some_strings_shown)
16793 printf (_(" No strings found in this section."));
16795 free (decomp_buf);
16796 free (real_start);
16798 putchar ('\n');
16799 return true;
16801 error_out:
16802 free (decomp_buf);
16803 free (real_start);
16804 return false;
16807 static bool
16808 dump_section_as_bytes (Elf_Internal_Shdr *section,
16809 Filedata *filedata,
16810 bool relocate)
16812 size_t bytes;
16813 uint64_t section_size;
16814 uint64_t addr;
16815 unsigned char *data;
16816 unsigned char *real_start;
16817 unsigned char *start;
16818 unsigned char *decomp_buf;
16820 real_start = start = (unsigned char *) get_section_contents (section, filedata);
16821 if (start == NULL)
16822 /* PR 21820: Do not fail if the section was empty. */
16823 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
16825 section_size = section->sh_size;
16827 if (filedata->is_separate)
16828 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
16829 printable_section_name (filedata, section),
16830 filedata->file_name);
16831 else
16832 printf (_("\nHex dump of section '%s':\n"),
16833 printable_section_name (filedata, section));
16835 decomp_buf = NULL;
16836 section_size = maybe_expand_or_relocate_section (section, filedata, &start,
16837 &decomp_buf, relocate);
16838 if (section_size == (uint64_t) -1)
16839 goto error_out;
16841 addr = section->sh_addr;
16842 bytes = section_size;
16843 data = start;
16845 while (bytes)
16847 int j;
16848 int k;
16849 int lbytes;
16851 lbytes = (bytes > 16 ? 16 : bytes);
16853 printf (" 0x%8.8" PRIx64 " ", addr);
16855 for (j = 0; j < 16; j++)
16857 if (j < lbytes)
16858 printf ("%2.2x", data[j]);
16859 else
16860 printf (" ");
16862 if ((j & 3) == 3)
16863 printf (" ");
16866 for (j = 0; j < lbytes; j++)
16868 k = data[j];
16869 if (k >= ' ' && k < 0x7f)
16870 printf ("%c", k);
16871 else
16872 printf (".");
16875 putchar ('\n');
16877 data += lbytes;
16878 addr += lbytes;
16879 bytes -= lbytes;
16882 free (decomp_buf);
16883 free (real_start);
16885 putchar ('\n');
16886 return true;
16888 error_out:
16889 free (decomp_buf);
16890 free (real_start);
16891 return false;
16894 #ifdef ENABLE_LIBCTF
16895 static ctf_sect_t *
16896 shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
16898 buf->cts_name = printable_section_name (filedata, shdr);
16899 buf->cts_size = shdr->sh_size;
16900 buf->cts_entsize = shdr->sh_entsize;
16902 return buf;
16905 /* Formatting callback function passed to ctf_dump. Returns either the pointer
16906 it is passed, or a pointer to newly-allocated storage, in which case
16907 dump_ctf() will free it when it no longer needs it. */
16909 static char *
16910 dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
16911 char *s, void *arg)
16913 const char *blanks = arg;
16914 return xasprintf ("%s%s", blanks, s);
16917 /* Dump CTF errors/warnings. */
16918 static void
16919 dump_ctf_errs (ctf_dict_t *fp)
16921 ctf_next_t *it = NULL;
16922 char *errtext;
16923 int is_warning;
16924 int err;
16926 /* Dump accumulated errors and warnings. */
16927 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
16929 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
16930 errtext);
16931 free (errtext);
16933 if (err != ECTF_NEXT_END)
16934 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
16937 /* Dump one CTF archive member. */
16939 static void
16940 dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
16941 size_t member)
16943 const char *things[] = {"Header", "Labels", "Data objects",
16944 "Function objects", "Variables", "Types", "Strings",
16945 ""};
16946 const char **thing;
16947 size_t i;
16949 /* Don't print out the name of the default-named archive member if it appears
16950 first in the list. The name .ctf appears everywhere, even for things that
16951 aren't really archives, so printing it out is liable to be confusing; also,
16952 the common case by far is for only one archive member to exist, and hiding
16953 it in that case seems worthwhile. */
16955 if (strcmp (name, ".ctf") != 0 || member != 0)
16956 printf (_("\nCTF archive member: %s:\n"), name);
16958 if (ctf_parent_name (ctf) != NULL)
16959 ctf_import (ctf, parent);
16961 for (i = 0, thing = things; *thing[0]; thing++, i++)
16963 ctf_dump_state_t *s = NULL;
16964 char *item;
16966 printf ("\n %s:\n", *thing);
16967 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
16968 (void *) " ")) != NULL)
16970 printf ("%s\n", item);
16971 free (item);
16974 if (ctf_errno (ctf))
16976 error (_("Iteration failed: %s, %s\n"), *thing,
16977 ctf_errmsg (ctf_errno (ctf)));
16978 break;
16982 dump_ctf_errs (ctf);
16985 static bool
16986 dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
16988 Elf_Internal_Shdr * symtab_sec = NULL;
16989 Elf_Internal_Shdr * strtab_sec = NULL;
16990 void * data = NULL;
16991 void * symdata = NULL;
16992 void * strdata = NULL;
16993 ctf_sect_t ctfsect, symsect, strsect;
16994 ctf_sect_t * symsectp = NULL;
16995 ctf_sect_t * strsectp = NULL;
16996 ctf_archive_t * ctfa = NULL;
16997 ctf_dict_t * parent = NULL;
16998 ctf_dict_t * fp;
17000 ctf_next_t *i = NULL;
17001 const char *name;
17002 size_t member = 0;
17003 int err;
17004 bool ret = false;
17006 shdr_to_ctf_sect (&ctfsect, section, filedata);
17007 data = get_section_contents (section, filedata);
17008 ctfsect.cts_data = data;
17010 if (!dump_ctf_symtab_name)
17011 dump_ctf_symtab_name = strdup (".dynsym");
17013 if (!dump_ctf_strtab_name)
17014 dump_ctf_strtab_name = strdup (".dynstr");
17016 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
17018 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
17020 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
17021 goto fail;
17023 if ((symdata = (void *) get_data (NULL, filedata,
17024 symtab_sec->sh_offset, 1,
17025 symtab_sec->sh_size,
17026 _("symbols"))) == NULL)
17027 goto fail;
17028 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
17029 symsect.cts_data = symdata;
17032 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
17034 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
17036 error (_("No string table section named %s\n"),
17037 dump_ctf_strtab_name);
17038 goto fail;
17040 if ((strdata = (void *) get_data (NULL, filedata,
17041 strtab_sec->sh_offset, 1,
17042 strtab_sec->sh_size,
17043 _("strings"))) == NULL)
17044 goto fail;
17045 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
17046 strsect.cts_data = strdata;
17049 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
17050 libctf papers over the difference, so we can pretend it is always an
17051 archive. */
17053 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
17055 dump_ctf_errs (NULL);
17056 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
17057 goto fail;
17060 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
17061 != ELFDATA2MSB);
17063 /* Preload the parent dict, since it will need to be imported into every
17064 child in turn. */
17065 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
17067 dump_ctf_errs (NULL);
17068 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
17069 goto fail;
17072 ret = true;
17074 if (filedata->is_separate)
17075 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
17076 printable_section_name (filedata, section),
17077 filedata->file_name);
17078 else
17079 printf (_("\nDump of CTF section '%s':\n"),
17080 printable_section_name (filedata, section));
17082 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
17083 dump_ctf_archive_member (fp, name, parent, member++);
17084 if (err != ECTF_NEXT_END)
17086 dump_ctf_errs (NULL);
17087 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
17088 ret = false;
17091 fail:
17092 ctf_dict_close (parent);
17093 ctf_close (ctfa);
17094 free (data);
17095 free (symdata);
17096 free (strdata);
17097 return ret;
17099 #endif
17101 static bool
17102 dump_section_as_sframe (Elf_Internal_Shdr * section, Filedata * filedata)
17104 void * data = NULL;
17105 sframe_decoder_ctx *sfd_ctx = NULL;
17106 const char *print_name = printable_section_name (filedata, section);
17108 bool ret = true;
17109 size_t sf_size;
17110 int err = 0;
17112 if (strcmp (print_name, "") == 0)
17114 error (_("Section name must be provided \n"));
17115 ret = false;
17116 return ret;
17119 data = get_section_contents (section, filedata);
17120 sf_size = section->sh_size;
17121 /* Decode the contents of the section. */
17122 sfd_ctx = sframe_decode ((const char*)data, sf_size, &err);
17123 if (!sfd_ctx)
17125 ret = false;
17126 error (_("SFrame decode failure: %s\n"), sframe_errmsg (err));
17127 goto fail;
17130 printf (_("Contents of the SFrame section %s:"), print_name);
17131 /* Dump the contents as text. */
17132 dump_sframe (sfd_ctx, section->sh_addr);
17134 fail:
17135 free (data);
17136 return ret;
17139 static bool
17140 load_specific_debug_section (enum dwarf_section_display_enum debug,
17141 const Elf_Internal_Shdr * sec,
17142 void * data)
17144 struct dwarf_section * section = &debug_displays [debug].section;
17145 char buf [64];
17146 Filedata * filedata = (Filedata *) data;
17148 if (section->start != NULL)
17150 /* If it is already loaded, do nothing. */
17151 if (streq (section->filename, filedata->file_name))
17152 return true;
17153 free (section->start);
17156 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
17157 section->address = sec->sh_addr;
17158 section->filename = filedata->file_name;
17159 section->start = (unsigned char *) get_data (NULL, filedata,
17160 sec->sh_offset, 1,
17161 sec->sh_size, buf);
17162 if (section->start == NULL)
17163 section->size = 0;
17164 else
17166 unsigned char *start = section->start;
17167 uint64_t size = sec->sh_size;
17168 uint64_t uncompressed_size = 0;
17169 bool is_zstd = false;
17171 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
17173 Elf_Internal_Chdr chdr;
17174 unsigned int compression_header_size;
17176 if (size < (is_32bit_elf
17177 ? sizeof (Elf32_External_Chdr)
17178 : sizeof (Elf64_External_Chdr)))
17180 warn (_("compressed section %s is too small to contain a compression header\n"),
17181 section->name);
17182 return false;
17185 compression_header_size = get_compression_header (&chdr, start, size);
17186 if (compression_header_size == 0)
17187 /* An error message will have already been generated
17188 by get_compression_header. */
17189 return false;
17191 if (chdr.ch_type == ch_compress_zlib)
17193 #ifdef HAVE_ZSTD
17194 else if (chdr.ch_type == ch_compress_zstd)
17195 is_zstd = true;
17196 #endif
17197 else
17199 warn (_("section '%s' has unsupported compress type: %d\n"),
17200 section->name, chdr.ch_type);
17201 return false;
17203 uncompressed_size = chdr.ch_size;
17204 start += compression_header_size;
17205 size -= compression_header_size;
17207 else if (size > 12 && streq ((char *) start, "ZLIB"))
17209 /* Read the zlib header. In this case, it should be "ZLIB"
17210 followed by the uncompressed section size, 8 bytes in
17211 big-endian order. */
17212 uncompressed_size = start[4]; uncompressed_size <<= 8;
17213 uncompressed_size += start[5]; uncompressed_size <<= 8;
17214 uncompressed_size += start[6]; uncompressed_size <<= 8;
17215 uncompressed_size += start[7]; uncompressed_size <<= 8;
17216 uncompressed_size += start[8]; uncompressed_size <<= 8;
17217 uncompressed_size += start[9]; uncompressed_size <<= 8;
17218 uncompressed_size += start[10]; uncompressed_size <<= 8;
17219 uncompressed_size += start[11];
17220 start += 12;
17221 size -= 12;
17224 if (uncompressed_size)
17226 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
17227 &size, filedata->file_size))
17229 /* Free the compressed buffer, update the section buffer
17230 and the section size if uncompress is successful. */
17231 free (section->start);
17232 section->start = start;
17234 else
17236 error (_("Unable to decompress section %s\n"),
17237 printable_section_name (filedata, sec));
17238 return false;
17242 section->size = size;
17245 if (section->start == NULL)
17246 return false;
17248 if (debug_displays [debug].relocate)
17250 if (! apply_relocations (filedata, sec, section->start, section->size,
17251 & section->reloc_info, & section->num_relocs))
17252 return false;
17254 else
17256 section->reloc_info = NULL;
17257 section->num_relocs = 0;
17260 return true;
17263 #if HAVE_LIBDEBUGINFOD
17264 /* Return a hex string representation of the build-id. */
17265 unsigned char *
17266 get_build_id (void * data)
17268 Filedata * filedata = (Filedata *) data;
17269 Elf_Internal_Shdr * shdr;
17270 size_t i;
17272 /* Iterate through notes to find note.gnu.build-id.
17273 FIXME: Only the first note in any note section is examined. */
17274 for (i = 0, shdr = filedata->section_headers;
17275 i < filedata->file_header.e_shnum && shdr != NULL;
17276 i++, shdr++)
17278 if (shdr->sh_type != SHT_NOTE)
17279 continue;
17281 char * next;
17282 char * end;
17283 size_t data_remaining;
17284 size_t min_notesz;
17285 Elf_External_Note * enote;
17286 Elf_Internal_Note inote;
17288 uint64_t offset = shdr->sh_offset;
17289 uint64_t align = shdr->sh_addralign;
17290 uint64_t length = shdr->sh_size;
17292 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
17293 if (enote == NULL)
17294 continue;
17296 if (align < 4)
17297 align = 4;
17298 else if (align != 4 && align != 8)
17300 free (enote);
17301 continue;
17304 end = (char *) enote + length;
17305 data_remaining = end - (char *) enote;
17307 if (!is_ia64_vms (filedata))
17309 min_notesz = offsetof (Elf_External_Note, name);
17310 if (data_remaining < min_notesz)
17312 warn (_("\
17313 malformed note encountered in section %s whilst scanning for build-id note\n"),
17314 printable_section_name (filedata, shdr));
17315 free (enote);
17316 continue;
17318 data_remaining -= min_notesz;
17320 inote.type = BYTE_GET (enote->type);
17321 inote.namesz = BYTE_GET (enote->namesz);
17322 inote.namedata = enote->name;
17323 inote.descsz = BYTE_GET (enote->descsz);
17324 inote.descdata = ((char *) enote
17325 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
17326 inote.descpos = offset + (inote.descdata - (char *) enote);
17327 next = ((char *) enote
17328 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
17330 else
17332 Elf64_External_VMS_Note *vms_enote;
17334 /* PR binutils/15191
17335 Make sure that there is enough data to read. */
17336 min_notesz = offsetof (Elf64_External_VMS_Note, name);
17337 if (data_remaining < min_notesz)
17339 warn (_("\
17340 malformed note encountered in section %s whilst scanning for build-id note\n"),
17341 printable_section_name (filedata, shdr));
17342 free (enote);
17343 continue;
17345 data_remaining -= min_notesz;
17347 vms_enote = (Elf64_External_VMS_Note *) enote;
17348 inote.type = BYTE_GET (vms_enote->type);
17349 inote.namesz = BYTE_GET (vms_enote->namesz);
17350 inote.namedata = vms_enote->name;
17351 inote.descsz = BYTE_GET (vms_enote->descsz);
17352 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
17353 inote.descpos = offset + (inote.descdata - (char *) enote);
17354 next = inote.descdata + align_power (inote.descsz, 3);
17357 /* Skip malformed notes. */
17358 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
17359 || (size_t) (inote.descdata - inote.namedata) > data_remaining
17360 || (size_t) (next - inote.descdata) < inote.descsz
17361 || ((size_t) (next - inote.descdata)
17362 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
17364 warn (_("\
17365 malformed note encountered in section %s whilst scanning for build-id note\n"),
17366 printable_section_name (filedata, shdr));
17367 free (enote);
17368 continue;
17371 /* Check if this is the build-id note. If so then convert the build-id
17372 bytes to a hex string. */
17373 if (inote.namesz > 0
17374 && startswith (inote.namedata, "GNU")
17375 && inote.type == NT_GNU_BUILD_ID)
17377 size_t j;
17378 char * build_id;
17380 build_id = malloc (inote.descsz * 2 + 1);
17381 if (build_id == NULL)
17383 free (enote);
17384 return NULL;
17387 for (j = 0; j < inote.descsz; ++j)
17388 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
17389 build_id[inote.descsz * 2] = '\0';
17390 free (enote);
17392 return (unsigned char *) build_id;
17394 free (enote);
17397 return NULL;
17399 #endif /* HAVE_LIBDEBUGINFOD */
17401 /* If this is not NULL, load_debug_section will only look for sections
17402 within the list of sections given here. */
17403 static unsigned int * section_subset = NULL;
17405 bool
17406 load_debug_section (enum dwarf_section_display_enum debug, void * data)
17408 struct dwarf_section * section = &debug_displays [debug].section;
17409 Elf_Internal_Shdr * sec;
17410 Filedata * filedata = (Filedata *) data;
17412 if (!dump_any_debugging)
17413 return false;
17415 /* Without section headers we cannot find any sections. */
17416 if (filedata->section_headers == NULL)
17417 return false;
17419 if (filedata->string_table == NULL
17420 && filedata->file_header.e_shstrndx != SHN_UNDEF
17421 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
17423 Elf_Internal_Shdr * strs;
17425 /* Read in the string table, so that we have section names to scan. */
17426 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
17428 if (strs != NULL && strs->sh_size != 0)
17430 filedata->string_table
17431 = (char *) get_data (NULL, filedata, strs->sh_offset,
17432 1, strs->sh_size, _("string table"));
17434 filedata->string_table_length
17435 = filedata->string_table != NULL ? strs->sh_size : 0;
17439 /* Locate the debug section. */
17440 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
17441 if (sec != NULL)
17442 section->name = section->uncompressed_name;
17443 else
17445 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
17446 if (sec != NULL)
17447 section->name = section->compressed_name;
17449 if (sec == NULL)
17450 return false;
17452 /* If we're loading from a subset of sections, and we've loaded
17453 a section matching this name before, it's likely that it's a
17454 different one. */
17455 if (section_subset != NULL)
17456 free_debug_section (debug);
17458 return load_specific_debug_section (debug, sec, data);
17461 void
17462 free_debug_section (enum dwarf_section_display_enum debug)
17464 struct dwarf_section * section = &debug_displays [debug].section;
17466 if (section->start == NULL)
17467 return;
17469 free ((char *) section->start);
17470 section->start = NULL;
17471 section->address = 0;
17472 section->size = 0;
17474 free (section->reloc_info);
17475 section->reloc_info = NULL;
17476 section->num_relocs = 0;
17479 static bool
17480 display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
17482 const char *name = (section_name_valid (filedata, section)
17483 ? section_name (filedata, section) : "");
17484 const char *print_name = printable_section_name (filedata, section);
17485 uint64_t length;
17486 bool result = true;
17487 int i;
17489 length = section->sh_size;
17490 if (length == 0)
17492 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
17493 return true;
17495 if (section->sh_type == SHT_NOBITS)
17497 /* There is no point in dumping the contents of a debugging section
17498 which has the NOBITS type - the bits in the file will be random.
17499 This can happen when a file containing a .eh_frame section is
17500 stripped with the --only-keep-debug command line option. */
17501 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
17502 print_name);
17503 return false;
17506 if (startswith (name, ".gnu.linkonce.wi."))
17507 name = ".debug_info";
17509 /* See if we know how to display the contents of this section. */
17510 for (i = 0; i < max; i++)
17512 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
17513 struct dwarf_section_display * display = debug_displays + i;
17514 struct dwarf_section * sec = & display->section;
17516 if (streq (sec->uncompressed_name, name)
17517 || (id == line && startswith (name, ".debug_line."))
17518 || streq (sec->compressed_name, name))
17520 bool secondary = (section != find_section (filedata, name));
17522 if (secondary)
17523 free_debug_section (id);
17525 if (i == line && startswith (name, ".debug_line."))
17526 sec->name = name;
17527 else if (streq (sec->uncompressed_name, name))
17528 sec->name = sec->uncompressed_name;
17529 else
17530 sec->name = sec->compressed_name;
17532 if (load_specific_debug_section (id, section, filedata))
17534 /* If this debug section is part of a CU/TU set in a .dwp file,
17535 restrict load_debug_section to the sections in that set. */
17536 section_subset = find_cu_tu_set (filedata, shndx);
17538 result &= display->display (sec, filedata);
17540 section_subset = NULL;
17542 if (secondary || (id != info && id != abbrev && id != debug_addr))
17543 free_debug_section (id);
17545 break;
17549 if (i == max)
17551 printf (_("Unrecognized debug section: %s\n"), print_name);
17552 result = false;
17555 return result;
17558 /* Set DUMP_SECTS for all sections where dumps were requested
17559 based on section name. */
17561 static void
17562 initialise_dumps_byname (Filedata * filedata)
17564 struct dump_list_entry * cur;
17566 for (cur = dump_sects_byname; cur; cur = cur->next)
17568 unsigned int i;
17569 bool any = false;
17571 for (i = 0; i < filedata->file_header.e_shnum; i++)
17572 if (section_name_valid (filedata, filedata->section_headers + i)
17573 && streq (section_name (filedata, filedata->section_headers + i),
17574 cur->name))
17576 request_dump_bynumber (&filedata->dump, i, cur->type);
17577 any = true;
17580 if (!any && !filedata->is_separate)
17581 warn (_("Section '%s' was not dumped because it does not exist\n"),
17582 cur->name);
17586 static bool
17587 process_section_contents (Filedata * filedata)
17589 Elf_Internal_Shdr * section;
17590 unsigned int i;
17591 bool res = true;
17593 if (! do_dump)
17594 return true;
17596 initialise_dumps_byname (filedata);
17598 for (i = 0, section = filedata->section_headers;
17599 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
17600 i++, section++)
17602 dump_type dump = filedata->dump.dump_sects[i];
17604 if (filedata->is_separate && ! process_links)
17605 dump &= DEBUG_DUMP;
17607 if (dump & AUTO_DUMP)
17609 switch (section->sh_type)
17611 case SHT_PROGBITS:
17612 /* FIXME: There are lots of different type of section that have
17613 SHT_PROGBITS set in their header - code, debug info, etc. So
17614 we should check the section's name and interpret its contents
17615 that way, rather than just defaulting to a byte dump. */
17616 #ifdef SUPPORT_DISASSEMBLY
17617 res &= disassemble_section (section, filedata);
17618 #else
17619 res &= dump_section_as_bytes (section, filedata, false);
17620 #endif
17621 break;
17623 case SHT_DYNSYM:
17624 case SHT_SYMTAB:
17625 res &= dump_symbol_section (section, filedata);
17626 break;
17628 case SHT_STRTAB:
17629 res &= dump_section_as_strings (section, filedata);
17630 break;
17632 case SHT_RELA:
17633 case SHT_REL:
17634 case SHT_RELR:
17635 res &= display_relocations (section, filedata);
17636 break;
17638 case SHT_NOTE:
17639 res &= process_notes_at (filedata, section, section->sh_offset,
17640 section->sh_size, section->sh_addralign);
17641 break;
17643 case SHT_NULL:
17644 inform (_("Unable to display section %d - it has a NULL type\n"), i);
17645 break;
17647 case SHT_NOBITS:
17648 inform (_("Unable to display section %d - it has no contents\n"), i);
17649 break;
17651 case SHT_HASH:
17652 case SHT_DYNAMIC:
17653 case SHT_GROUP:
17654 case SHT_GNU_ATTRIBUTES:
17655 /* FIXME: Implement these. */
17656 /* Fall through. */
17657 default:
17658 /* FIXME: Add Proc and OS specific section types ? */
17659 warn (_("Unable to determine how to dump section %d (type %#x)\n"),
17660 i, section->sh_type);
17661 res = false;
17662 break;
17666 #ifdef SUPPORT_DISASSEMBLY
17667 if (dump & DISASS_DUMP)
17669 if (! disassemble_section (section, filedata))
17670 res = false;
17672 #endif
17673 if (dump & HEX_DUMP)
17675 if (! dump_section_as_bytes (section, filedata, false))
17676 res = false;
17679 if (dump & RELOC_DUMP)
17681 if (! dump_section_as_bytes (section, filedata, true))
17682 res = false;
17685 if (dump & STRING_DUMP)
17687 if (! dump_section_as_strings (section, filedata))
17688 res = false;
17691 if (dump & DEBUG_DUMP)
17693 if (! display_debug_section (i, section, filedata))
17694 res = false;
17697 #ifdef ENABLE_LIBCTF
17698 if (dump & CTF_DUMP)
17700 if (! dump_section_as_ctf (section, filedata))
17701 res = false;
17703 #endif
17704 if (dump & SFRAME_DUMP)
17706 if (! dump_section_as_sframe (section, filedata))
17707 res = false;
17711 if (! filedata->is_separate)
17713 /* Check to see if the user requested a
17714 dump of a section that does not exist. */
17715 for (; i < filedata->dump.num_dump_sects; i++)
17716 if (filedata->dump.dump_sects[i])
17718 warn (_("Section %d was not dumped because it does not exist!\n"), i);
17719 res = false;
17723 return res;
17726 static void
17727 process_mips_fpe_exception (int mask)
17729 if (mask)
17731 bool first = true;
17733 if (mask & OEX_FPU_INEX)
17734 fputs ("INEX", stdout), first = false;
17735 if (mask & OEX_FPU_UFLO)
17736 printf ("%sUFLO", first ? "" : "|"), first = false;
17737 if (mask & OEX_FPU_OFLO)
17738 printf ("%sOFLO", first ? "" : "|"), first = false;
17739 if (mask & OEX_FPU_DIV0)
17740 printf ("%sDIV0", first ? "" : "|"), first = false;
17741 if (mask & OEX_FPU_INVAL)
17742 printf ("%sINVAL", first ? "" : "|");
17744 else
17745 fputs ("0", stdout);
17748 /* Display's the value of TAG at location P. If TAG is
17749 greater than 0 it is assumed to be an unknown tag, and
17750 a message is printed to this effect. Otherwise it is
17751 assumed that a message has already been printed.
17753 If the bottom bit of TAG is set it assumed to have a
17754 string value, otherwise it is assumed to have an integer
17755 value.
17757 Returns an updated P pointing to the first unread byte
17758 beyond the end of TAG's value.
17760 Reads at or beyond END will not be made. */
17762 static unsigned char *
17763 display_tag_value (signed int tag,
17764 unsigned char * p,
17765 const unsigned char * const end)
17767 uint64_t val;
17769 if (tag > 0)
17770 printf (" Tag_unknown_%d: ", tag);
17772 if (p >= end)
17774 warn (_("<corrupt tag>\n"));
17776 else if (tag & 1)
17778 /* PR 17531 file: 027-19978-0.004. */
17779 size_t maxlen = (end - p) - 1;
17781 putchar ('"');
17782 if (maxlen > 0)
17784 print_symbol_name ((int) maxlen, (const char *) p);
17785 p += strnlen ((char *) p, maxlen) + 1;
17787 else
17789 printf (_("<corrupt string tag>"));
17790 p = (unsigned char *) end;
17792 printf ("\"\n");
17794 else
17796 READ_ULEB (val, p, end);
17797 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
17800 assert (p <= end);
17801 return p;
17804 /* ARC ABI attributes section. */
17806 static unsigned char *
17807 display_arc_attribute (unsigned char * p,
17808 const unsigned char * const end)
17810 unsigned int tag;
17811 unsigned int val;
17813 READ_ULEB (tag, p, end);
17815 switch (tag)
17817 case Tag_ARC_PCS_config:
17818 READ_ULEB (val, p, end);
17819 printf (" Tag_ARC_PCS_config: ");
17820 switch (val)
17822 case 0:
17823 printf (_("Absent/Non standard\n"));
17824 break;
17825 case 1:
17826 printf (_("Bare metal/mwdt\n"));
17827 break;
17828 case 2:
17829 printf (_("Bare metal/newlib\n"));
17830 break;
17831 case 3:
17832 printf (_("Linux/uclibc\n"));
17833 break;
17834 case 4:
17835 printf (_("Linux/glibc\n"));
17836 break;
17837 default:
17838 printf (_("Unknown\n"));
17839 break;
17841 break;
17843 case Tag_ARC_CPU_base:
17844 READ_ULEB (val, p, end);
17845 printf (" Tag_ARC_CPU_base: ");
17846 switch (val)
17848 default:
17849 case TAG_CPU_NONE:
17850 printf (_("Absent\n"));
17851 break;
17852 case TAG_CPU_ARC6xx:
17853 printf ("ARC6xx\n");
17854 break;
17855 case TAG_CPU_ARC7xx:
17856 printf ("ARC7xx\n");
17857 break;
17858 case TAG_CPU_ARCEM:
17859 printf ("ARCEM\n");
17860 break;
17861 case TAG_CPU_ARCHS:
17862 printf ("ARCHS\n");
17863 break;
17865 break;
17867 case Tag_ARC_CPU_variation:
17868 READ_ULEB (val, p, end);
17869 printf (" Tag_ARC_CPU_variation: ");
17870 switch (val)
17872 default:
17873 if (val > 0 && val < 16)
17874 printf ("Core%d\n", val);
17875 else
17876 printf ("Unknown\n");
17877 break;
17879 case 0:
17880 printf (_("Absent\n"));
17881 break;
17883 break;
17885 case Tag_ARC_CPU_name:
17886 printf (" Tag_ARC_CPU_name: ");
17887 p = display_tag_value (-1, p, end);
17888 break;
17890 case Tag_ARC_ABI_rf16:
17891 READ_ULEB (val, p, end);
17892 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
17893 break;
17895 case Tag_ARC_ABI_osver:
17896 READ_ULEB (val, p, end);
17897 printf (" Tag_ARC_ABI_osver: v%d\n", val);
17898 break;
17900 case Tag_ARC_ABI_pic:
17901 case Tag_ARC_ABI_sda:
17902 READ_ULEB (val, p, end);
17903 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
17904 : " Tag_ARC_ABI_pic: ");
17905 switch (val)
17907 case 0:
17908 printf (_("Absent\n"));
17909 break;
17910 case 1:
17911 printf ("MWDT\n");
17912 break;
17913 case 2:
17914 printf ("GNU\n");
17915 break;
17916 default:
17917 printf (_("Unknown\n"));
17918 break;
17920 break;
17922 case Tag_ARC_ABI_tls:
17923 READ_ULEB (val, p, end);
17924 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
17925 break;
17927 case Tag_ARC_ABI_enumsize:
17928 READ_ULEB (val, p, end);
17929 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
17930 _("smallest"));
17931 break;
17933 case Tag_ARC_ABI_exceptions:
17934 READ_ULEB (val, p, end);
17935 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
17936 : _("default"));
17937 break;
17939 case Tag_ARC_ABI_double_size:
17940 READ_ULEB (val, p, end);
17941 printf (" Tag_ARC_ABI_double_size: %d\n", val);
17942 break;
17944 case Tag_ARC_ISA_config:
17945 printf (" Tag_ARC_ISA_config: ");
17946 p = display_tag_value (-1, p, end);
17947 break;
17949 case Tag_ARC_ISA_apex:
17950 printf (" Tag_ARC_ISA_apex: ");
17951 p = display_tag_value (-1, p, end);
17952 break;
17954 case Tag_ARC_ISA_mpy_option:
17955 READ_ULEB (val, p, end);
17956 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
17957 break;
17959 case Tag_ARC_ATR_version:
17960 READ_ULEB (val, p, end);
17961 printf (" Tag_ARC_ATR_version: %d\n", val);
17962 break;
17964 default:
17965 return display_tag_value (tag & 1, p, end);
17968 return p;
17971 /* ARM EABI attributes section. */
17972 typedef struct
17974 unsigned int tag;
17975 const char * name;
17976 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
17977 unsigned int type;
17978 const char *const *table;
17979 } arm_attr_public_tag;
17981 static const char *const arm_attr_tag_CPU_arch[] =
17982 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
17983 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
17984 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
17985 "v8.1-M.mainline", "v9"};
17986 static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
17987 static const char *const arm_attr_tag_THUMB_ISA_use[] =
17988 {"No", "Thumb-1", "Thumb-2", "Yes"};
17989 static const char *const arm_attr_tag_FP_arch[] =
17990 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
17991 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
17992 static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
17993 static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
17994 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
17995 "NEON for ARMv8.1"};
17996 static const char *const arm_attr_tag_PCS_config[] =
17997 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
17998 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
17999 static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
18000 {"V6", "SB", "TLS", "Unused"};
18001 static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
18002 {"Absolute", "PC-relative", "SB-relative", "None"};
18003 static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
18004 {"Absolute", "PC-relative", "None"};
18005 static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
18006 {"None", "direct", "GOT-indirect"};
18007 static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
18008 {"None", "??? 1", "2", "??? 3", "4"};
18009 static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
18010 static const char *const arm_attr_tag_ABI_FP_denormal[] =
18011 {"Unused", "Needed", "Sign only"};
18012 static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
18013 static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
18014 static const char *const arm_attr_tag_ABI_FP_number_model[] =
18015 {"Unused", "Finite", "RTABI", "IEEE 754"};
18016 static const char *const arm_attr_tag_ABI_enum_size[] =
18017 {"Unused", "small", "int", "forced to int"};
18018 static const char *const arm_attr_tag_ABI_HardFP_use[] =
18019 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
18020 static const char *const arm_attr_tag_ABI_VFP_args[] =
18021 {"AAPCS", "VFP registers", "custom", "compatible"};
18022 static const char *const arm_attr_tag_ABI_WMMX_args[] =
18023 {"AAPCS", "WMMX registers", "custom"};
18024 static const char *const arm_attr_tag_ABI_optimization_goals[] =
18025 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
18026 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
18027 static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
18028 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
18029 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
18030 static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
18031 static const char *const arm_attr_tag_FP_HP_extension[] =
18032 {"Not Allowed", "Allowed"};
18033 static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
18034 {"None", "IEEE 754", "Alternative Format"};
18035 static const char *const arm_attr_tag_DSP_extension[] =
18036 {"Follow architecture", "Allowed"};
18037 static const char *const arm_attr_tag_MPextension_use[] =
18038 {"Not Allowed", "Allowed"};
18039 static const char *const arm_attr_tag_DIV_use[] =
18040 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
18041 "Allowed in v7-A with integer division extension"};
18042 static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
18043 static const char *const arm_attr_tag_Virtualization_use[] =
18044 {"Not Allowed", "TrustZone", "Virtualization Extensions",
18045 "TrustZone and Virtualization Extensions"};
18046 static const char *const arm_attr_tag_MPextension_use_legacy[] =
18047 {"Not Allowed", "Allowed"};
18049 static const char *const arm_attr_tag_MVE_arch[] =
18050 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
18052 static const char * arm_attr_tag_PAC_extension[] =
18053 {"No PAC/AUT instructions",
18054 "PAC/AUT instructions permitted in the NOP space",
18055 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
18057 static const char * arm_attr_tag_BTI_extension[] =
18058 {"BTI instructions not permitted",
18059 "BTI instructions permitted in the NOP space",
18060 "BTI instructions permitted in the NOP and in the non-NOP space"};
18062 static const char * arm_attr_tag_BTI_use[] =
18063 {"Compiled without branch target enforcement",
18064 "Compiled with branch target enforcement"};
18066 static const char * arm_attr_tag_PACRET_use[] =
18067 {"Compiled without return address signing and authentication",
18068 "Compiled with return address signing and authentication"};
18070 #define LOOKUP(id, name) \
18071 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
18072 static arm_attr_public_tag arm_attr_public_tags[] =
18074 {4, "CPU_raw_name", 1, NULL},
18075 {5, "CPU_name", 1, NULL},
18076 LOOKUP(6, CPU_arch),
18077 {7, "CPU_arch_profile", 0, NULL},
18078 LOOKUP(8, ARM_ISA_use),
18079 LOOKUP(9, THUMB_ISA_use),
18080 LOOKUP(10, FP_arch),
18081 LOOKUP(11, WMMX_arch),
18082 LOOKUP(12, Advanced_SIMD_arch),
18083 LOOKUP(13, PCS_config),
18084 LOOKUP(14, ABI_PCS_R9_use),
18085 LOOKUP(15, ABI_PCS_RW_data),
18086 LOOKUP(16, ABI_PCS_RO_data),
18087 LOOKUP(17, ABI_PCS_GOT_use),
18088 LOOKUP(18, ABI_PCS_wchar_t),
18089 LOOKUP(19, ABI_FP_rounding),
18090 LOOKUP(20, ABI_FP_denormal),
18091 LOOKUP(21, ABI_FP_exceptions),
18092 LOOKUP(22, ABI_FP_user_exceptions),
18093 LOOKUP(23, ABI_FP_number_model),
18094 {24, "ABI_align_needed", 0, NULL},
18095 {25, "ABI_align_preserved", 0, NULL},
18096 LOOKUP(26, ABI_enum_size),
18097 LOOKUP(27, ABI_HardFP_use),
18098 LOOKUP(28, ABI_VFP_args),
18099 LOOKUP(29, ABI_WMMX_args),
18100 LOOKUP(30, ABI_optimization_goals),
18101 LOOKUP(31, ABI_FP_optimization_goals),
18102 {32, "compatibility", 0, NULL},
18103 LOOKUP(34, CPU_unaligned_access),
18104 LOOKUP(36, FP_HP_extension),
18105 LOOKUP(38, ABI_FP_16bit_format),
18106 LOOKUP(42, MPextension_use),
18107 LOOKUP(44, DIV_use),
18108 LOOKUP(46, DSP_extension),
18109 LOOKUP(48, MVE_arch),
18110 LOOKUP(50, PAC_extension),
18111 LOOKUP(52, BTI_extension),
18112 LOOKUP(74, BTI_use),
18113 LOOKUP(76, PACRET_use),
18114 {64, "nodefaults", 0, NULL},
18115 {65, "also_compatible_with", 0, NULL},
18116 LOOKUP(66, T2EE_use),
18117 {67, "conformance", 1, NULL},
18118 LOOKUP(68, Virtualization_use),
18119 LOOKUP(70, MPextension_use_legacy)
18121 #undef LOOKUP
18123 static unsigned char *
18124 display_arm_attribute (unsigned char * p,
18125 const unsigned char * const end)
18127 unsigned int tag;
18128 unsigned int val;
18129 arm_attr_public_tag * attr;
18130 unsigned i;
18131 unsigned int type;
18133 READ_ULEB (tag, p, end);
18134 attr = NULL;
18135 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
18137 if (arm_attr_public_tags[i].tag == tag)
18139 attr = &arm_attr_public_tags[i];
18140 break;
18144 if (attr)
18146 printf (" Tag_%s: ", attr->name);
18147 switch (attr->type)
18149 case 0:
18150 switch (tag)
18152 case 7: /* Tag_CPU_arch_profile. */
18153 READ_ULEB (val, p, end);
18154 switch (val)
18156 case 0: printf (_("None\n")); break;
18157 case 'A': printf (_("Application\n")); break;
18158 case 'R': printf (_("Realtime\n")); break;
18159 case 'M': printf (_("Microcontroller\n")); break;
18160 case 'S': printf (_("Application or Realtime\n")); break;
18161 default: printf ("??? (%d)\n", val); break;
18163 break;
18165 case 24: /* Tag_align_needed. */
18166 READ_ULEB (val, p, end);
18167 switch (val)
18169 case 0: printf (_("None\n")); break;
18170 case 1: printf (_("8-byte\n")); break;
18171 case 2: printf (_("4-byte\n")); break;
18172 case 3: printf ("??? 3\n"); break;
18173 default:
18174 if (val <= 12)
18175 printf (_("8-byte and up to %d-byte extended\n"),
18176 1 << val);
18177 else
18178 printf ("??? (%d)\n", val);
18179 break;
18181 break;
18183 case 25: /* Tag_align_preserved. */
18184 READ_ULEB (val, p, end);
18185 switch (val)
18187 case 0: printf (_("None\n")); break;
18188 case 1: printf (_("8-byte, except leaf SP\n")); break;
18189 case 2: printf (_("8-byte\n")); break;
18190 case 3: printf ("??? 3\n"); break;
18191 default:
18192 if (val <= 12)
18193 printf (_("8-byte and up to %d-byte extended\n"),
18194 1 << val);
18195 else
18196 printf ("??? (%d)\n", val);
18197 break;
18199 break;
18201 case 32: /* Tag_compatibility. */
18203 READ_ULEB (val, p, end);
18204 printf (_("flag = %d, vendor = "), val);
18205 if (p < end - 1)
18207 size_t maxlen = (end - p) - 1;
18209 print_symbol_name ((int) maxlen, (const char *) p);
18210 p += strnlen ((char *) p, maxlen) + 1;
18212 else
18214 printf (_("<corrupt>"));
18215 p = (unsigned char *) end;
18217 putchar ('\n');
18219 break;
18221 case 64: /* Tag_nodefaults. */
18222 /* PR 17531: file: 001-505008-0.01. */
18223 if (p < end)
18224 p++;
18225 printf (_("True\n"));
18226 break;
18228 case 65: /* Tag_also_compatible_with. */
18229 READ_ULEB (val, p, end);
18230 if (val == 6 /* Tag_CPU_arch. */)
18232 READ_ULEB (val, p, end);
18233 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
18234 printf ("??? (%d)\n", val);
18235 else
18236 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
18238 else
18239 printf ("???\n");
18240 while (p < end && *(p++) != '\0' /* NUL terminator. */)
18242 break;
18244 default:
18245 printf (_("<unknown: %d>\n"), tag);
18246 break;
18248 return p;
18250 case 1:
18251 return display_tag_value (-1, p, end);
18252 case 2:
18253 return display_tag_value (0, p, end);
18255 default:
18256 assert (attr->type & 0x80);
18257 READ_ULEB (val, p, end);
18258 type = attr->type & 0x7f;
18259 if (val >= type)
18260 printf ("??? (%d)\n", val);
18261 else
18262 printf ("%s\n", attr->table[val]);
18263 return p;
18267 return display_tag_value (tag, p, end);
18270 static unsigned char *
18271 display_gnu_attribute (unsigned char * p,
18272 unsigned char * (* display_proc_gnu_attribute)
18273 (unsigned char *, unsigned int, const unsigned char * const),
18274 const unsigned char * const end)
18276 unsigned int tag;
18277 unsigned int val;
18279 READ_ULEB (tag, p, end);
18281 /* Tag_compatibility is the only generic GNU attribute defined at
18282 present. */
18283 if (tag == 32)
18285 READ_ULEB (val, p, end);
18287 printf (_("flag = %d, vendor = "), val);
18288 if (p == end)
18290 printf (_("<corrupt>\n"));
18291 warn (_("corrupt vendor attribute\n"));
18293 else
18295 if (p < end - 1)
18297 size_t maxlen = (end - p) - 1;
18299 print_symbol_name ((int) maxlen, (const char *) p);
18300 p += strnlen ((char *) p, maxlen) + 1;
18302 else
18304 printf (_("<corrupt>"));
18305 p = (unsigned char *) end;
18307 putchar ('\n');
18309 return p;
18312 if ((tag & 2) == 0 && display_proc_gnu_attribute)
18313 return display_proc_gnu_attribute (p, tag, end);
18315 return display_tag_value (tag, p, end);
18318 static unsigned char *
18319 display_m68k_gnu_attribute (unsigned char * p,
18320 unsigned int tag,
18321 const unsigned char * const end)
18323 unsigned int val;
18325 if (tag == Tag_GNU_M68K_ABI_FP)
18327 printf (" Tag_GNU_M68K_ABI_FP: ");
18328 if (p == end)
18330 printf (_("<corrupt>\n"));
18331 return p;
18333 READ_ULEB (val, p, end);
18335 if (val > 3)
18336 printf ("(%#x), ", val);
18338 switch (val & 3)
18340 case 0:
18341 printf (_("unspecified hard/soft float\n"));
18342 break;
18343 case 1:
18344 printf (_("hard float\n"));
18345 break;
18346 case 2:
18347 printf (_("soft float\n"));
18348 break;
18350 return p;
18353 return display_tag_value (tag & 1, p, end);
18356 static unsigned char *
18357 display_power_gnu_attribute (unsigned char * p,
18358 unsigned int tag,
18359 const unsigned char * const end)
18361 unsigned int val;
18363 if (tag == Tag_GNU_Power_ABI_FP)
18365 printf (" Tag_GNU_Power_ABI_FP: ");
18366 if (p == end)
18368 printf (_("<corrupt>\n"));
18369 return p;
18371 READ_ULEB (val, p, end);
18373 if (val > 15)
18374 printf ("(%#x), ", val);
18376 switch (val & 3)
18378 case 0:
18379 printf (_("unspecified hard/soft float, "));
18380 break;
18381 case 1:
18382 printf (_("hard float, "));
18383 break;
18384 case 2:
18385 printf (_("soft float, "));
18386 break;
18387 case 3:
18388 printf (_("single-precision hard float, "));
18389 break;
18392 switch (val & 0xC)
18394 case 0:
18395 printf (_("unspecified long double\n"));
18396 break;
18397 case 4:
18398 printf (_("128-bit IBM long double\n"));
18399 break;
18400 case 8:
18401 printf (_("64-bit long double\n"));
18402 break;
18403 case 12:
18404 printf (_("128-bit IEEE long double\n"));
18405 break;
18407 return p;
18410 if (tag == Tag_GNU_Power_ABI_Vector)
18412 printf (" Tag_GNU_Power_ABI_Vector: ");
18413 if (p == end)
18415 printf (_("<corrupt>\n"));
18416 return p;
18418 READ_ULEB (val, p, end);
18420 if (val > 3)
18421 printf ("(%#x), ", val);
18423 switch (val & 3)
18425 case 0:
18426 printf (_("unspecified\n"));
18427 break;
18428 case 1:
18429 printf (_("generic\n"));
18430 break;
18431 case 2:
18432 printf ("AltiVec\n");
18433 break;
18434 case 3:
18435 printf ("SPE\n");
18436 break;
18438 return p;
18441 if (tag == Tag_GNU_Power_ABI_Struct_Return)
18443 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
18444 if (p == end)
18446 printf (_("<corrupt>\n"));
18447 return p;
18449 READ_ULEB (val, p, end);
18451 if (val > 2)
18452 printf ("(%#x), ", val);
18454 switch (val & 3)
18456 case 0:
18457 printf (_("unspecified\n"));
18458 break;
18459 case 1:
18460 printf ("r3/r4\n");
18461 break;
18462 case 2:
18463 printf (_("memory\n"));
18464 break;
18465 case 3:
18466 printf ("???\n");
18467 break;
18469 return p;
18472 return display_tag_value (tag & 1, p, end);
18475 static unsigned char *
18476 display_s390_gnu_attribute (unsigned char * p,
18477 unsigned int tag,
18478 const unsigned char * const end)
18480 unsigned int val;
18482 if (tag == Tag_GNU_S390_ABI_Vector)
18484 printf (" Tag_GNU_S390_ABI_Vector: ");
18485 READ_ULEB (val, p, end);
18487 switch (val)
18489 case 0:
18490 printf (_("any\n"));
18491 break;
18492 case 1:
18493 printf (_("software\n"));
18494 break;
18495 case 2:
18496 printf (_("hardware\n"));
18497 break;
18498 default:
18499 printf ("??? (%d)\n", val);
18500 break;
18502 return p;
18505 return display_tag_value (tag & 1, p, end);
18508 static void
18509 display_sparc_hwcaps (unsigned int mask)
18511 if (mask)
18513 bool first = true;
18515 if (mask & ELF_SPARC_HWCAP_MUL32)
18516 fputs ("mul32", stdout), first = false;
18517 if (mask & ELF_SPARC_HWCAP_DIV32)
18518 printf ("%sdiv32", first ? "" : "|"), first = false;
18519 if (mask & ELF_SPARC_HWCAP_FSMULD)
18520 printf ("%sfsmuld", first ? "" : "|"), first = false;
18521 if (mask & ELF_SPARC_HWCAP_V8PLUS)
18522 printf ("%sv8plus", first ? "" : "|"), first = false;
18523 if (mask & ELF_SPARC_HWCAP_POPC)
18524 printf ("%spopc", first ? "" : "|"), first = false;
18525 if (mask & ELF_SPARC_HWCAP_VIS)
18526 printf ("%svis", first ? "" : "|"), first = false;
18527 if (mask & ELF_SPARC_HWCAP_VIS2)
18528 printf ("%svis2", first ? "" : "|"), first = false;
18529 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
18530 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
18531 if (mask & ELF_SPARC_HWCAP_FMAF)
18532 printf ("%sfmaf", first ? "" : "|"), first = false;
18533 if (mask & ELF_SPARC_HWCAP_VIS3)
18534 printf ("%svis3", first ? "" : "|"), first = false;
18535 if (mask & ELF_SPARC_HWCAP_HPC)
18536 printf ("%shpc", first ? "" : "|"), first = false;
18537 if (mask & ELF_SPARC_HWCAP_RANDOM)
18538 printf ("%srandom", first ? "" : "|"), first = false;
18539 if (mask & ELF_SPARC_HWCAP_TRANS)
18540 printf ("%strans", first ? "" : "|"), first = false;
18541 if (mask & ELF_SPARC_HWCAP_FJFMAU)
18542 printf ("%sfjfmau", first ? "" : "|"), first = false;
18543 if (mask & ELF_SPARC_HWCAP_IMA)
18544 printf ("%sima", first ? "" : "|"), first = false;
18545 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
18546 printf ("%scspare", first ? "" : "|"), first = false;
18548 else
18549 fputc ('0', stdout);
18550 fputc ('\n', stdout);
18553 static void
18554 display_sparc_hwcaps2 (unsigned int mask)
18556 if (mask)
18558 bool first = true;
18560 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
18561 fputs ("fjathplus", stdout), first = false;
18562 if (mask & ELF_SPARC_HWCAP2_VIS3B)
18563 printf ("%svis3b", first ? "" : "|"), first = false;
18564 if (mask & ELF_SPARC_HWCAP2_ADP)
18565 printf ("%sadp", first ? "" : "|"), first = false;
18566 if (mask & ELF_SPARC_HWCAP2_SPARC5)
18567 printf ("%ssparc5", first ? "" : "|"), first = false;
18568 if (mask & ELF_SPARC_HWCAP2_MWAIT)
18569 printf ("%smwait", first ? "" : "|"), first = false;
18570 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
18571 printf ("%sxmpmul", first ? "" : "|"), first = false;
18572 if (mask & ELF_SPARC_HWCAP2_XMONT)
18573 printf ("%sxmont2", first ? "" : "|"), first = false;
18574 if (mask & ELF_SPARC_HWCAP2_NSEC)
18575 printf ("%snsec", first ? "" : "|"), first = false;
18576 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
18577 printf ("%sfjathhpc", first ? "" : "|"), first = false;
18578 if (mask & ELF_SPARC_HWCAP2_FJDES)
18579 printf ("%sfjdes", first ? "" : "|"), first = false;
18580 if (mask & ELF_SPARC_HWCAP2_FJAES)
18581 printf ("%sfjaes", first ? "" : "|"), first = false;
18583 else
18584 fputc ('0', stdout);
18585 fputc ('\n', stdout);
18588 static unsigned char *
18589 display_sparc_gnu_attribute (unsigned char * p,
18590 unsigned int tag,
18591 const unsigned char * const end)
18593 unsigned int val;
18595 if (tag == Tag_GNU_Sparc_HWCAPS)
18597 READ_ULEB (val, p, end);
18598 printf (" Tag_GNU_Sparc_HWCAPS: ");
18599 display_sparc_hwcaps (val);
18600 return p;
18602 if (tag == Tag_GNU_Sparc_HWCAPS2)
18604 READ_ULEB (val, p, end);
18605 printf (" Tag_GNU_Sparc_HWCAPS2: ");
18606 display_sparc_hwcaps2 (val);
18607 return p;
18610 return display_tag_value (tag, p, end);
18613 static void
18614 print_mips_fp_abi_value (unsigned int val)
18616 switch (val)
18618 case Val_GNU_MIPS_ABI_FP_ANY:
18619 printf (_("Hard or soft float\n"));
18620 break;
18621 case Val_GNU_MIPS_ABI_FP_DOUBLE:
18622 printf (_("Hard float (double precision)\n"));
18623 break;
18624 case Val_GNU_MIPS_ABI_FP_SINGLE:
18625 printf (_("Hard float (single precision)\n"));
18626 break;
18627 case Val_GNU_MIPS_ABI_FP_SOFT:
18628 printf (_("Soft float\n"));
18629 break;
18630 case Val_GNU_MIPS_ABI_FP_OLD_64:
18631 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
18632 break;
18633 case Val_GNU_MIPS_ABI_FP_XX:
18634 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
18635 break;
18636 case Val_GNU_MIPS_ABI_FP_64:
18637 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
18638 break;
18639 case Val_GNU_MIPS_ABI_FP_64A:
18640 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
18641 break;
18642 case Val_GNU_MIPS_ABI_FP_NAN2008:
18643 printf (_("NaN 2008 compatibility\n"));
18644 break;
18645 default:
18646 printf ("??? (%d)\n", val);
18647 break;
18651 static unsigned char *
18652 display_mips_gnu_attribute (unsigned char * p,
18653 unsigned int tag,
18654 const unsigned char * const end)
18656 if (tag == Tag_GNU_MIPS_ABI_FP)
18658 unsigned int val;
18660 printf (" Tag_GNU_MIPS_ABI_FP: ");
18661 READ_ULEB (val, p, end);
18662 print_mips_fp_abi_value (val);
18663 return p;
18666 if (tag == Tag_GNU_MIPS_ABI_MSA)
18668 unsigned int val;
18670 printf (" Tag_GNU_MIPS_ABI_MSA: ");
18671 READ_ULEB (val, p, end);
18673 switch (val)
18675 case Val_GNU_MIPS_ABI_MSA_ANY:
18676 printf (_("Any MSA or not\n"));
18677 break;
18678 case Val_GNU_MIPS_ABI_MSA_128:
18679 printf (_("128-bit MSA\n"));
18680 break;
18681 default:
18682 printf ("??? (%d)\n", val);
18683 break;
18685 return p;
18688 return display_tag_value (tag & 1, p, end);
18691 static unsigned char *
18692 display_tic6x_attribute (unsigned char * p,
18693 const unsigned char * const end)
18695 unsigned int tag;
18696 unsigned int val;
18698 READ_ULEB (tag, p, end);
18700 switch (tag)
18702 case Tag_ISA:
18703 printf (" Tag_ISA: ");
18704 READ_ULEB (val, p, end);
18706 switch (val)
18708 case C6XABI_Tag_ISA_none:
18709 printf (_("None\n"));
18710 break;
18711 case C6XABI_Tag_ISA_C62X:
18712 printf ("C62x\n");
18713 break;
18714 case C6XABI_Tag_ISA_C67X:
18715 printf ("C67x\n");
18716 break;
18717 case C6XABI_Tag_ISA_C67XP:
18718 printf ("C67x+\n");
18719 break;
18720 case C6XABI_Tag_ISA_C64X:
18721 printf ("C64x\n");
18722 break;
18723 case C6XABI_Tag_ISA_C64XP:
18724 printf ("C64x+\n");
18725 break;
18726 case C6XABI_Tag_ISA_C674X:
18727 printf ("C674x\n");
18728 break;
18729 default:
18730 printf ("??? (%d)\n", val);
18731 break;
18733 return p;
18735 case Tag_ABI_wchar_t:
18736 printf (" Tag_ABI_wchar_t: ");
18737 READ_ULEB (val, p, end);
18738 switch (val)
18740 case 0:
18741 printf (_("Not used\n"));
18742 break;
18743 case 1:
18744 printf (_("2 bytes\n"));
18745 break;
18746 case 2:
18747 printf (_("4 bytes\n"));
18748 break;
18749 default:
18750 printf ("??? (%d)\n", val);
18751 break;
18753 return p;
18755 case Tag_ABI_stack_align_needed:
18756 printf (" Tag_ABI_stack_align_needed: ");
18757 READ_ULEB (val, p, end);
18758 switch (val)
18760 case 0:
18761 printf (_("8-byte\n"));
18762 break;
18763 case 1:
18764 printf (_("16-byte\n"));
18765 break;
18766 default:
18767 printf ("??? (%d)\n", val);
18768 break;
18770 return p;
18772 case Tag_ABI_stack_align_preserved:
18773 READ_ULEB (val, p, end);
18774 printf (" Tag_ABI_stack_align_preserved: ");
18775 switch (val)
18777 case 0:
18778 printf (_("8-byte\n"));
18779 break;
18780 case 1:
18781 printf (_("16-byte\n"));
18782 break;
18783 default:
18784 printf ("??? (%d)\n", val);
18785 break;
18787 return p;
18789 case Tag_ABI_DSBT:
18790 READ_ULEB (val, p, end);
18791 printf (" Tag_ABI_DSBT: ");
18792 switch (val)
18794 case 0:
18795 printf (_("DSBT addressing not used\n"));
18796 break;
18797 case 1:
18798 printf (_("DSBT addressing used\n"));
18799 break;
18800 default:
18801 printf ("??? (%d)\n", val);
18802 break;
18804 return p;
18806 case Tag_ABI_PID:
18807 READ_ULEB (val, p, end);
18808 printf (" Tag_ABI_PID: ");
18809 switch (val)
18811 case 0:
18812 printf (_("Data addressing position-dependent\n"));
18813 break;
18814 case 1:
18815 printf (_("Data addressing position-independent, GOT near DP\n"));
18816 break;
18817 case 2:
18818 printf (_("Data addressing position-independent, GOT far from DP\n"));
18819 break;
18820 default:
18821 printf ("??? (%d)\n", val);
18822 break;
18824 return p;
18826 case Tag_ABI_PIC:
18827 READ_ULEB (val, p, end);
18828 printf (" Tag_ABI_PIC: ");
18829 switch (val)
18831 case 0:
18832 printf (_("Code addressing position-dependent\n"));
18833 break;
18834 case 1:
18835 printf (_("Code addressing position-independent\n"));
18836 break;
18837 default:
18838 printf ("??? (%d)\n", val);
18839 break;
18841 return p;
18843 case Tag_ABI_array_object_alignment:
18844 READ_ULEB (val, p, end);
18845 printf (" Tag_ABI_array_object_alignment: ");
18846 switch (val)
18848 case 0:
18849 printf (_("8-byte\n"));
18850 break;
18851 case 1:
18852 printf (_("4-byte\n"));
18853 break;
18854 case 2:
18855 printf (_("16-byte\n"));
18856 break;
18857 default:
18858 printf ("??? (%d)\n", val);
18859 break;
18861 return p;
18863 case Tag_ABI_array_object_align_expected:
18864 READ_ULEB (val, p, end);
18865 printf (" Tag_ABI_array_object_align_expected: ");
18866 switch (val)
18868 case 0:
18869 printf (_("8-byte\n"));
18870 break;
18871 case 1:
18872 printf (_("4-byte\n"));
18873 break;
18874 case 2:
18875 printf (_("16-byte\n"));
18876 break;
18877 default:
18878 printf ("??? (%d)\n", val);
18879 break;
18881 return p;
18883 case Tag_ABI_compatibility:
18885 READ_ULEB (val, p, end);
18886 printf (" Tag_ABI_compatibility: ");
18887 printf (_("flag = %d, vendor = "), val);
18888 if (p < end - 1)
18890 size_t maxlen = (end - p) - 1;
18892 print_symbol_name ((int) maxlen, (const char *) p);
18893 p += strnlen ((char *) p, maxlen) + 1;
18895 else
18897 printf (_("<corrupt>"));
18898 p = (unsigned char *) end;
18900 putchar ('\n');
18901 return p;
18904 case Tag_ABI_conformance:
18906 printf (" Tag_ABI_conformance: \"");
18907 if (p < end - 1)
18909 size_t maxlen = (end - p) - 1;
18911 print_symbol_name ((int) maxlen, (const char *) p);
18912 p += strnlen ((char *) p, maxlen) + 1;
18914 else
18916 printf (_("<corrupt>"));
18917 p = (unsigned char *) end;
18919 printf ("\"\n");
18920 return p;
18924 return display_tag_value (tag, p, end);
18927 static void
18928 display_raw_attribute (unsigned char * p, unsigned char const * const end)
18930 uint64_t addr = 0;
18931 size_t bytes = end - p;
18933 assert (end >= p);
18934 while (bytes)
18936 int j;
18937 int k;
18938 int lbytes = (bytes > 16 ? 16 : bytes);
18940 printf (" 0x%8.8" PRIx64 " ", addr);
18942 for (j = 0; j < 16; j++)
18944 if (j < lbytes)
18945 printf ("%2.2x", p[j]);
18946 else
18947 printf (" ");
18949 if ((j & 3) == 3)
18950 printf (" ");
18953 for (j = 0; j < lbytes; j++)
18955 k = p[j];
18956 if (k >= ' ' && k < 0x7f)
18957 printf ("%c", k);
18958 else
18959 printf (".");
18962 putchar ('\n');
18964 p += lbytes;
18965 bytes -= lbytes;
18966 addr += lbytes;
18969 putchar ('\n');
18972 static unsigned char *
18973 display_msp430_attribute (unsigned char * p,
18974 const unsigned char * const end)
18976 uint64_t val;
18977 uint64_t tag;
18979 READ_ULEB (tag, p, end);
18981 switch (tag)
18983 case OFBA_MSPABI_Tag_ISA:
18984 printf (" Tag_ISA: ");
18985 READ_ULEB (val, p, end);
18986 switch (val)
18988 case 0: printf (_("None\n")); break;
18989 case 1: printf (_("MSP430\n")); break;
18990 case 2: printf (_("MSP430X\n")); break;
18991 default: printf ("??? (%" PRId64 ")\n", val); break;
18993 break;
18995 case OFBA_MSPABI_Tag_Code_Model:
18996 printf (" Tag_Code_Model: ");
18997 READ_ULEB (val, p, end);
18998 switch (val)
19000 case 0: printf (_("None\n")); break;
19001 case 1: printf (_("Small\n")); break;
19002 case 2: printf (_("Large\n")); break;
19003 default: printf ("??? (%" PRId64 ")\n", val); break;
19005 break;
19007 case OFBA_MSPABI_Tag_Data_Model:
19008 printf (" Tag_Data_Model: ");
19009 READ_ULEB (val, p, end);
19010 switch (val)
19012 case 0: printf (_("None\n")); break;
19013 case 1: printf (_("Small\n")); break;
19014 case 2: printf (_("Large\n")); break;
19015 case 3: printf (_("Restricted Large\n")); break;
19016 default: printf ("??? (%" PRId64 ")\n", val); break;
19018 break;
19020 default:
19021 printf (_(" <unknown tag %" PRId64 ">: "), tag);
19023 if (tag & 1)
19025 putchar ('"');
19026 if (p < end - 1)
19028 size_t maxlen = (end - p) - 1;
19030 print_symbol_name ((int) maxlen, (const char *) p);
19031 p += strnlen ((char *) p, maxlen) + 1;
19033 else
19035 printf (_("<corrupt>"));
19036 p = (unsigned char *) end;
19038 printf ("\"\n");
19040 else
19042 READ_ULEB (val, p, end);
19043 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
19045 break;
19048 assert (p <= end);
19049 return p;
19052 static unsigned char *
19053 display_msp430_gnu_attribute (unsigned char * p,
19054 unsigned int tag,
19055 const unsigned char * const end)
19057 if (tag == Tag_GNU_MSP430_Data_Region)
19059 uint64_t val;
19061 printf (" Tag_GNU_MSP430_Data_Region: ");
19062 READ_ULEB (val, p, end);
19064 switch (val)
19066 case Val_GNU_MSP430_Data_Region_Any:
19067 printf (_("Any Region\n"));
19068 break;
19069 case Val_GNU_MSP430_Data_Region_Lower:
19070 printf (_("Lower Region Only\n"));
19071 break;
19072 default:
19073 printf ("??? (%" PRIu64 ")\n", val);
19075 return p;
19077 return display_tag_value (tag & 1, p, end);
19080 struct riscv_attr_tag_t {
19081 const char *name;
19082 unsigned int tag;
19085 static struct riscv_attr_tag_t riscv_attr_tag[] =
19087 #define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
19088 T(arch),
19089 T(priv_spec),
19090 T(priv_spec_minor),
19091 T(priv_spec_revision),
19092 T(unaligned_access),
19093 T(stack_align),
19094 #undef T
19097 static unsigned char *
19098 display_riscv_attribute (unsigned char *p,
19099 const unsigned char * const end)
19101 uint64_t val;
19102 uint64_t tag;
19103 struct riscv_attr_tag_t *attr = NULL;
19104 unsigned i;
19106 READ_ULEB (tag, p, end);
19108 /* Find the name of attribute. */
19109 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
19111 if (riscv_attr_tag[i].tag == tag)
19113 attr = &riscv_attr_tag[i];
19114 break;
19118 if (attr)
19119 printf (" %s: ", attr->name);
19120 else
19121 return display_tag_value (tag, p, end);
19123 switch (tag)
19125 case Tag_RISCV_priv_spec:
19126 case Tag_RISCV_priv_spec_minor:
19127 case Tag_RISCV_priv_spec_revision:
19128 READ_ULEB (val, p, end);
19129 printf ("%" PRIu64 "\n", val);
19130 break;
19131 case Tag_RISCV_unaligned_access:
19132 READ_ULEB (val, p, end);
19133 switch (val)
19135 case 0:
19136 printf (_("No unaligned access\n"));
19137 break;
19138 case 1:
19139 printf (_("Unaligned access\n"));
19140 break;
19142 break;
19143 case Tag_RISCV_stack_align:
19144 READ_ULEB (val, p, end);
19145 printf (_("%" PRIu64 "-bytes\n"), val);
19146 break;
19147 case Tag_RISCV_arch:
19148 p = display_tag_value (-1, p, end);
19149 break;
19150 default:
19151 return display_tag_value (tag, p, end);
19154 return p;
19157 static unsigned char *
19158 display_csky_attribute (unsigned char * p,
19159 const unsigned char * const end)
19161 uint64_t tag;
19162 uint64_t val;
19163 READ_ULEB (tag, p, end);
19165 if (tag >= Tag_CSKY_MAX)
19167 return display_tag_value (-1, p, end);
19170 switch (tag)
19172 case Tag_CSKY_ARCH_NAME:
19173 printf (" Tag_CSKY_ARCH_NAME:\t\t");
19174 return display_tag_value (-1, p, end);
19175 case Tag_CSKY_CPU_NAME:
19176 printf (" Tag_CSKY_CPU_NAME:\t\t");
19177 return display_tag_value (-1, p, end);
19179 case Tag_CSKY_ISA_FLAGS:
19180 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
19181 return display_tag_value (0, p, end);
19182 case Tag_CSKY_ISA_EXT_FLAGS:
19183 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
19184 return display_tag_value (0, p, end);
19186 case Tag_CSKY_DSP_VERSION:
19187 printf (" Tag_CSKY_DSP_VERSION:\t\t");
19188 READ_ULEB (val, p, end);
19189 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
19190 printf ("DSP Extension\n");
19191 else if (val == VAL_CSKY_DSP_VERSION_2)
19192 printf ("DSP 2.0\n");
19193 break;
19195 case Tag_CSKY_VDSP_VERSION:
19196 printf (" Tag_CSKY_VDSP_VERSION:\t");
19197 READ_ULEB (val, p, end);
19198 printf ("VDSP Version %" PRId64 "\n", val);
19199 break;
19201 case Tag_CSKY_FPU_VERSION:
19202 printf (" Tag_CSKY_FPU_VERSION:\t\t");
19203 READ_ULEB (val, p, end);
19204 if (val == VAL_CSKY_FPU_VERSION_1)
19205 printf ("ABIV1 FPU Version 1\n");
19206 else if (val == VAL_CSKY_FPU_VERSION_2)
19207 printf ("FPU Version 2\n");
19208 break;
19210 case Tag_CSKY_FPU_ABI:
19211 printf (" Tag_CSKY_FPU_ABI:\t\t");
19212 READ_ULEB (val, p, end);
19213 if (val == VAL_CSKY_FPU_ABI_HARD)
19214 printf ("Hard\n");
19215 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
19216 printf ("SoftFP\n");
19217 else if (val == VAL_CSKY_FPU_ABI_SOFT)
19218 printf ("Soft\n");
19219 break;
19220 case Tag_CSKY_FPU_ROUNDING:
19221 READ_ULEB (val, p, end);
19222 if (val == 1)
19224 printf (" Tag_CSKY_FPU_ROUNDING:\t");
19225 printf ("Needed\n");
19227 break;
19228 case Tag_CSKY_FPU_DENORMAL:
19229 READ_ULEB (val, p, end);
19230 if (val == 1)
19232 printf (" Tag_CSKY_FPU_DENORMAL:\t");
19233 printf ("Needed\n");
19235 break;
19236 case Tag_CSKY_FPU_Exception:
19237 READ_ULEB (val, p, end);
19238 if (val == 1)
19240 printf (" Tag_CSKY_FPU_Exception:\t");
19241 printf ("Needed\n");
19243 break;
19244 case Tag_CSKY_FPU_NUMBER_MODULE:
19245 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
19246 return display_tag_value (-1, p, end);
19247 case Tag_CSKY_FPU_HARDFP:
19248 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
19249 READ_ULEB (val, p, end);
19250 if (val & VAL_CSKY_FPU_HARDFP_HALF)
19251 printf (" Half");
19252 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
19253 printf (" Single");
19254 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
19255 printf (" Double");
19256 printf ("\n");
19257 break;
19258 default:
19259 return display_tag_value (tag, p, end);
19261 return p;
19264 static bool
19265 process_attributes (Filedata * filedata,
19266 const char * public_name,
19267 unsigned int proc_type,
19268 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
19269 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
19271 Elf_Internal_Shdr * sect;
19272 unsigned i;
19273 bool res = true;
19275 /* Find the section header so that we get the size. */
19276 for (i = 0, sect = filedata->section_headers;
19277 i < filedata->file_header.e_shnum;
19278 i++, sect++)
19280 unsigned char * contents;
19281 unsigned char * p;
19283 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
19284 continue;
19286 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
19287 sect->sh_size, _("attributes"));
19288 if (contents == NULL)
19290 res = false;
19291 continue;
19294 p = contents;
19295 /* The first character is the version of the attributes.
19296 Currently only version 1, (aka 'A') is recognised here. */
19297 if (*p != 'A')
19299 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
19300 res = false;
19302 else
19304 uint64_t section_len;
19306 section_len = sect->sh_size - 1;
19307 p++;
19309 while (section_len > 0)
19311 uint64_t attr_len;
19312 unsigned int namelen;
19313 bool public_section;
19314 bool gnu_section;
19316 if (section_len <= 4)
19318 error (_("Tag section ends prematurely\n"));
19319 res = false;
19320 break;
19322 attr_len = byte_get (p, 4);
19323 p += 4;
19325 if (attr_len > section_len)
19327 error (_("Bad attribute length (%u > %u)\n"),
19328 (unsigned) attr_len, (unsigned) section_len);
19329 attr_len = section_len;
19330 res = false;
19332 /* PR 17531: file: 001-101425-0.004 */
19333 else if (attr_len < 5)
19335 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
19336 res = false;
19337 break;
19340 section_len -= attr_len;
19341 attr_len -= 4;
19343 namelen = strnlen ((char *) p, attr_len) + 1;
19344 if (namelen == 0 || namelen >= attr_len)
19346 error (_("Corrupt attribute section name\n"));
19347 res = false;
19348 break;
19351 printf (_("Attribute Section: "));
19352 print_symbol_name (INT_MAX, (const char *) p);
19353 putchar ('\n');
19355 if (public_name && streq ((char *) p, public_name))
19356 public_section = true;
19357 else
19358 public_section = false;
19360 if (streq ((char *) p, "gnu"))
19361 gnu_section = true;
19362 else
19363 gnu_section = false;
19365 p += namelen;
19366 attr_len -= namelen;
19368 while (attr_len > 0 && p < contents + sect->sh_size)
19370 int tag;
19371 unsigned int val;
19372 uint64_t size;
19373 unsigned char * end;
19375 /* PR binutils/17531: Safe handling of corrupt files. */
19376 if (attr_len < 6)
19378 error (_("Unused bytes at end of section\n"));
19379 res = false;
19380 section_len = 0;
19381 break;
19384 tag = *(p++);
19385 size = byte_get (p, 4);
19386 if (size > attr_len)
19388 error (_("Bad subsection length (%u > %u)\n"),
19389 (unsigned) size, (unsigned) attr_len);
19390 res = false;
19391 size = attr_len;
19393 /* PR binutils/17531: Safe handling of corrupt files. */
19394 if (size < 6)
19396 error (_("Bad subsection length (%u < 6)\n"),
19397 (unsigned) size);
19398 res = false;
19399 section_len = 0;
19400 break;
19403 attr_len -= size;
19404 end = p + size - 1;
19405 assert (end <= contents + sect->sh_size);
19406 p += 4;
19408 switch (tag)
19410 case 1:
19411 printf (_("File Attributes\n"));
19412 break;
19413 case 2:
19414 printf (_("Section Attributes:"));
19415 goto do_numlist;
19416 case 3:
19417 printf (_("Symbol Attributes:"));
19418 /* Fall through. */
19419 do_numlist:
19420 for (;;)
19422 READ_ULEB (val, p, end);
19423 if (val == 0)
19424 break;
19425 printf (" %d", val);
19427 printf ("\n");
19428 break;
19429 default:
19430 printf (_("Unknown tag: %d\n"), tag);
19431 public_section = false;
19432 break;
19435 if (public_section && display_pub_attribute != NULL)
19437 while (p < end)
19438 p = display_pub_attribute (p, end);
19439 assert (p == end);
19441 else if (gnu_section && display_proc_gnu_attribute != NULL)
19443 while (p < end)
19444 p = display_gnu_attribute (p,
19445 display_proc_gnu_attribute,
19446 end);
19447 assert (p == end);
19449 else if (p < end)
19451 printf (_(" Unknown attribute:\n"));
19452 display_raw_attribute (p, end);
19453 p = end;
19455 else
19456 attr_len = 0;
19461 free (contents);
19464 return res;
19467 /* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
19468 Print the Address, Access and Initial fields of an entry at VMA ADDR
19469 and return the VMA of the next entry, or -1 if there was a problem.
19470 Does not read from DATA_END or beyond. */
19472 static uint64_t
19473 print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
19474 unsigned char * data_end)
19476 printf (" ");
19477 print_vma (addr, LONG_HEX);
19478 printf (" ");
19479 if (addr < pltgot + 0xfff0)
19480 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
19481 else
19482 printf ("%10s", "");
19483 printf (" ");
19484 if (data == NULL)
19485 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
19486 else
19488 uint64_t entry;
19489 unsigned char * from = data + addr - pltgot;
19491 if (from + (is_32bit_elf ? 4 : 8) > data_end)
19493 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
19494 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
19495 return (uint64_t) -1;
19497 else
19499 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
19500 print_vma (entry, LONG_HEX);
19503 return addr + (is_32bit_elf ? 4 : 8);
19506 /* DATA points to the contents of a MIPS PLT GOT that starts at VMA
19507 PLTGOT. Print the Address and Initial fields of an entry at VMA
19508 ADDR and return the VMA of the next entry. */
19510 static uint64_t
19511 print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
19513 printf (" ");
19514 print_vma (addr, LONG_HEX);
19515 printf (" ");
19516 if (data == NULL)
19517 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
19518 else
19520 uint64_t entry;
19522 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
19523 print_vma (entry, LONG_HEX);
19525 return addr + (is_32bit_elf ? 4 : 8);
19528 static void
19529 print_mips_ases (unsigned int mask)
19531 if (mask & AFL_ASE_DSP)
19532 fputs ("\n\tDSP ASE", stdout);
19533 if (mask & AFL_ASE_DSPR2)
19534 fputs ("\n\tDSP R2 ASE", stdout);
19535 if (mask & AFL_ASE_DSPR3)
19536 fputs ("\n\tDSP R3 ASE", stdout);
19537 if (mask & AFL_ASE_EVA)
19538 fputs ("\n\tEnhanced VA Scheme", stdout);
19539 if (mask & AFL_ASE_MCU)
19540 fputs ("\n\tMCU (MicroController) ASE", stdout);
19541 if (mask & AFL_ASE_MDMX)
19542 fputs ("\n\tMDMX ASE", stdout);
19543 if (mask & AFL_ASE_MIPS3D)
19544 fputs ("\n\tMIPS-3D ASE", stdout);
19545 if (mask & AFL_ASE_MT)
19546 fputs ("\n\tMT ASE", stdout);
19547 if (mask & AFL_ASE_SMARTMIPS)
19548 fputs ("\n\tSmartMIPS ASE", stdout);
19549 if (mask & AFL_ASE_VIRT)
19550 fputs ("\n\tVZ ASE", stdout);
19551 if (mask & AFL_ASE_MSA)
19552 fputs ("\n\tMSA ASE", stdout);
19553 if (mask & AFL_ASE_MIPS16)
19554 fputs ("\n\tMIPS16 ASE", stdout);
19555 if (mask & AFL_ASE_MICROMIPS)
19556 fputs ("\n\tMICROMIPS ASE", stdout);
19557 if (mask & AFL_ASE_XPA)
19558 fputs ("\n\tXPA ASE", stdout);
19559 if (mask & AFL_ASE_MIPS16E2)
19560 fputs ("\n\tMIPS16e2 ASE", stdout);
19561 if (mask & AFL_ASE_CRC)
19562 fputs ("\n\tCRC ASE", stdout);
19563 if (mask & AFL_ASE_GINV)
19564 fputs ("\n\tGINV ASE", stdout);
19565 if (mask & AFL_ASE_LOONGSON_MMI)
19566 fputs ("\n\tLoongson MMI ASE", stdout);
19567 if (mask & AFL_ASE_LOONGSON_CAM)
19568 fputs ("\n\tLoongson CAM ASE", stdout);
19569 if (mask & AFL_ASE_LOONGSON_EXT)
19570 fputs ("\n\tLoongson EXT ASE", stdout);
19571 if (mask & AFL_ASE_LOONGSON_EXT2)
19572 fputs ("\n\tLoongson EXT2 ASE", stdout);
19573 if (mask == 0)
19574 fprintf (stdout, "\n\t%s", _("None"));
19575 else if ((mask & ~AFL_ASE_MASK) != 0)
19576 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
19579 static void
19580 print_mips_isa_ext (unsigned int isa_ext)
19582 switch (isa_ext)
19584 case 0:
19585 fputs (_("None"), stdout);
19586 break;
19587 case AFL_EXT_XLR:
19588 fputs ("RMI XLR", stdout);
19589 break;
19590 case AFL_EXT_OCTEON3:
19591 fputs ("Cavium Networks Octeon3", stdout);
19592 break;
19593 case AFL_EXT_OCTEON2:
19594 fputs ("Cavium Networks Octeon2", stdout);
19595 break;
19596 case AFL_EXT_OCTEONP:
19597 fputs ("Cavium Networks OcteonP", stdout);
19598 break;
19599 case AFL_EXT_OCTEON:
19600 fputs ("Cavium Networks Octeon", stdout);
19601 break;
19602 case AFL_EXT_5900:
19603 fputs ("Toshiba R5900", stdout);
19604 break;
19605 case AFL_EXT_4650:
19606 fputs ("MIPS R4650", stdout);
19607 break;
19608 case AFL_EXT_4010:
19609 fputs ("LSI R4010", stdout);
19610 break;
19611 case AFL_EXT_4100:
19612 fputs ("NEC VR4100", stdout);
19613 break;
19614 case AFL_EXT_3900:
19615 fputs ("Toshiba R3900", stdout);
19616 break;
19617 case AFL_EXT_10000:
19618 fputs ("MIPS R10000", stdout);
19619 break;
19620 case AFL_EXT_SB1:
19621 fputs ("Broadcom SB-1", stdout);
19622 break;
19623 case AFL_EXT_4111:
19624 fputs ("NEC VR4111/VR4181", stdout);
19625 break;
19626 case AFL_EXT_4120:
19627 fputs ("NEC VR4120", stdout);
19628 break;
19629 case AFL_EXT_5400:
19630 fputs ("NEC VR5400", stdout);
19631 break;
19632 case AFL_EXT_5500:
19633 fputs ("NEC VR5500", stdout);
19634 break;
19635 case AFL_EXT_LOONGSON_2E:
19636 fputs ("ST Microelectronics Loongson 2E", stdout);
19637 break;
19638 case AFL_EXT_LOONGSON_2F:
19639 fputs ("ST Microelectronics Loongson 2F", stdout);
19640 break;
19641 case AFL_EXT_INTERAPTIV_MR2:
19642 fputs ("Imagination interAptiv MR2", stdout);
19643 break;
19644 default:
19645 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
19649 static signed int
19650 get_mips_reg_size (int reg_size)
19652 return (reg_size == AFL_REG_NONE) ? 0
19653 : (reg_size == AFL_REG_32) ? 32
19654 : (reg_size == AFL_REG_64) ? 64
19655 : (reg_size == AFL_REG_128) ? 128
19656 : -1;
19659 static bool
19660 process_mips_specific (Filedata * filedata)
19662 Elf_Internal_Dyn * entry;
19663 Elf_Internal_Shdr *sect = NULL;
19664 size_t liblist_offset = 0;
19665 size_t liblistno = 0;
19666 size_t conflictsno = 0;
19667 size_t options_offset = 0;
19668 size_t conflicts_offset = 0;
19669 size_t pltrelsz = 0;
19670 size_t pltrel = 0;
19671 uint64_t pltgot = 0;
19672 uint64_t mips_pltgot = 0;
19673 uint64_t jmprel = 0;
19674 uint64_t local_gotno = 0;
19675 uint64_t gotsym = 0;
19676 uint64_t symtabno = 0;
19677 bool res = true;
19679 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
19680 display_mips_gnu_attribute))
19681 res = false;
19683 sect = find_section (filedata, ".MIPS.abiflags");
19685 if (sect != NULL)
19687 Elf_External_ABIFlags_v0 *abiflags_ext;
19688 Elf_Internal_ABIFlags_v0 abiflags_in;
19690 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
19692 error (_("Corrupt MIPS ABI Flags section.\n"));
19693 res = false;
19695 else
19697 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
19698 sect->sh_size, _("MIPS ABI Flags section"));
19699 if (abiflags_ext)
19701 abiflags_in.version = BYTE_GET (abiflags_ext->version);
19702 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
19703 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
19704 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
19705 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
19706 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
19707 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
19708 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
19709 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
19710 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
19711 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
19713 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
19714 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
19715 if (abiflags_in.isa_rev > 1)
19716 printf ("r%d", abiflags_in.isa_rev);
19717 printf ("\nGPR size: %d",
19718 get_mips_reg_size (abiflags_in.gpr_size));
19719 printf ("\nCPR1 size: %d",
19720 get_mips_reg_size (abiflags_in.cpr1_size));
19721 printf ("\nCPR2 size: %d",
19722 get_mips_reg_size (abiflags_in.cpr2_size));
19723 fputs ("\nFP ABI: ", stdout);
19724 print_mips_fp_abi_value (abiflags_in.fp_abi);
19725 fputs ("ISA Extension: ", stdout);
19726 print_mips_isa_ext (abiflags_in.isa_ext);
19727 fputs ("\nASEs:", stdout);
19728 print_mips_ases (abiflags_in.ases);
19729 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
19730 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
19731 fputc ('\n', stdout);
19732 free (abiflags_ext);
19737 /* We have a lot of special sections. Thanks SGI! */
19738 if (filedata->dynamic_section == NULL)
19740 /* No dynamic information available. See if there is static GOT. */
19741 sect = find_section (filedata, ".got");
19742 if (sect != NULL)
19744 unsigned char *data_end;
19745 unsigned char *data;
19746 uint64_t ent, end;
19747 int addr_size;
19749 pltgot = sect->sh_addr;
19751 ent = pltgot;
19752 addr_size = (is_32bit_elf ? 4 : 8);
19753 end = pltgot + sect->sh_size;
19755 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
19756 end - pltgot, 1,
19757 _("Global Offset Table data"));
19758 /* PR 12855: Null data is handled gracefully throughout. */
19759 data_end = data + (end - pltgot);
19761 printf (_("\nStatic GOT:\n"));
19762 printf (_(" Canonical gp value: "));
19763 print_vma (ent + 0x7ff0, LONG_HEX);
19764 printf ("\n\n");
19766 /* In a dynamic binary GOT[0] is reserved for the dynamic
19767 loader to store the lazy resolver pointer, however in
19768 a static binary it may well have been omitted and GOT
19769 reduced to a table of addresses.
19770 PR 21344: Check for the entry being fully available
19771 before fetching it. */
19772 if (data
19773 && data + ent - pltgot + addr_size <= data_end
19774 && byte_get (data + ent - pltgot, addr_size) == 0)
19776 printf (_(" Reserved entries:\n"));
19777 printf (_(" %*s %10s %*s\n"),
19778 addr_size * 2, _("Address"), _("Access"),
19779 addr_size * 2, _("Value"));
19780 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19781 printf ("\n");
19782 if (ent == (uint64_t) -1)
19783 goto sgot_print_fail;
19785 /* Check for the MSB of GOT[1] being set, identifying a
19786 GNU object. This entry will be used by some runtime
19787 loaders, to store the module pointer. Otherwise this
19788 is an ordinary local entry.
19789 PR 21344: Check for the entry being fully available
19790 before fetching it. */
19791 if (data
19792 && data + ent - pltgot + addr_size <= data_end
19793 && (byte_get (data + ent - pltgot, addr_size)
19794 >> (addr_size * 8 - 1)) != 0)
19796 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19797 printf ("\n");
19798 if (ent == (uint64_t) -1)
19799 goto sgot_print_fail;
19801 printf ("\n");
19804 if (data != NULL && ent < end)
19806 printf (_(" Local entries:\n"));
19807 printf (" %*s %10s %*s\n",
19808 addr_size * 2, _("Address"), _("Access"),
19809 addr_size * 2, _("Value"));
19810 while (ent < end)
19812 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19813 printf ("\n");
19814 if (ent == (uint64_t) -1)
19815 goto sgot_print_fail;
19817 printf ("\n");
19820 sgot_print_fail:
19821 free (data);
19823 return res;
19826 for (entry = filedata->dynamic_section;
19827 /* PR 17531 file: 012-50589-0.004. */
19828 (entry < filedata->dynamic_section + filedata->dynamic_nent
19829 && entry->d_tag != DT_NULL);
19830 ++entry)
19831 switch (entry->d_tag)
19833 case DT_MIPS_LIBLIST:
19834 liblist_offset
19835 = offset_from_vma (filedata, entry->d_un.d_val,
19836 liblistno * sizeof (Elf32_External_Lib));
19837 break;
19838 case DT_MIPS_LIBLISTNO:
19839 liblistno = entry->d_un.d_val;
19840 break;
19841 case DT_MIPS_OPTIONS:
19842 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
19843 break;
19844 case DT_MIPS_CONFLICT:
19845 conflicts_offset
19846 = offset_from_vma (filedata, entry->d_un.d_val,
19847 conflictsno * sizeof (Elf32_External_Conflict));
19848 break;
19849 case DT_MIPS_CONFLICTNO:
19850 conflictsno = entry->d_un.d_val;
19851 break;
19852 case DT_PLTGOT:
19853 pltgot = entry->d_un.d_ptr;
19854 break;
19855 case DT_MIPS_LOCAL_GOTNO:
19856 local_gotno = entry->d_un.d_val;
19857 break;
19858 case DT_MIPS_GOTSYM:
19859 gotsym = entry->d_un.d_val;
19860 break;
19861 case DT_MIPS_SYMTABNO:
19862 symtabno = entry->d_un.d_val;
19863 break;
19864 case DT_MIPS_PLTGOT:
19865 mips_pltgot = entry->d_un.d_ptr;
19866 break;
19867 case DT_PLTREL:
19868 pltrel = entry->d_un.d_val;
19869 break;
19870 case DT_PLTRELSZ:
19871 pltrelsz = entry->d_un.d_val;
19872 break;
19873 case DT_JMPREL:
19874 jmprel = entry->d_un.d_ptr;
19875 break;
19876 default:
19877 break;
19880 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
19882 Elf32_External_Lib * elib;
19883 size_t cnt;
19885 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
19886 sizeof (Elf32_External_Lib),
19887 liblistno,
19888 _("liblist section data"));
19889 if (elib)
19891 printf (ngettext ("\nSection '.liblist' contains %zu entry:\n",
19892 "\nSection '.liblist' contains %zu entries:\n",
19893 liblistno),
19894 liblistno);
19895 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
19896 stdout);
19898 for (cnt = 0; cnt < liblistno; ++cnt)
19900 Elf32_Lib liblist;
19901 time_t atime;
19902 char timebuf[128];
19903 struct tm * tmp;
19905 liblist.l_name = BYTE_GET (elib[cnt].l_name);
19906 atime = BYTE_GET (elib[cnt].l_time_stamp);
19907 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19908 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19909 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19911 tmp = gmtime (&atime);
19912 snprintf (timebuf, sizeof (timebuf),
19913 "%04u-%02u-%02uT%02u:%02u:%02u",
19914 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19915 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
19917 printf ("%3zu: ", cnt);
19918 if (valid_dynamic_name (filedata, liblist.l_name))
19919 print_symbol_name (20, get_dynamic_name (filedata, liblist.l_name));
19920 else
19921 printf (_("<corrupt: %9ld>"), liblist.l_name);
19922 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
19923 liblist.l_version);
19925 if (liblist.l_flags == 0)
19926 puts (_(" NONE"));
19927 else
19929 static const struct
19931 const char * name;
19932 int bit;
19934 l_flags_vals[] =
19936 { " EXACT_MATCH", LL_EXACT_MATCH },
19937 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
19938 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
19939 { " EXPORTS", LL_EXPORTS },
19940 { " DELAY_LOAD", LL_DELAY_LOAD },
19941 { " DELTA", LL_DELTA }
19943 int flags = liblist.l_flags;
19944 size_t fcnt;
19946 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
19947 if ((flags & l_flags_vals[fcnt].bit) != 0)
19949 fputs (l_flags_vals[fcnt].name, stdout);
19950 flags ^= l_flags_vals[fcnt].bit;
19952 if (flags != 0)
19953 printf (" %#x", (unsigned int) flags);
19955 puts ("");
19959 free (elib);
19961 else
19962 res = false;
19965 if (options_offset != 0)
19967 Elf_External_Options * eopt;
19968 size_t offset;
19969 int cnt;
19971 /* Find the section header so that we get the size. */
19972 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
19973 /* PR 17533 file: 012-277276-0.004. */
19974 if (sect == NULL)
19976 error (_("No MIPS_OPTIONS header found\n"));
19977 return false;
19979 /* PR 24243 */
19980 if (sect->sh_size < sizeof (* eopt))
19982 error (_("The MIPS options section is too small.\n"));
19983 return false;
19986 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
19987 sect->sh_size, _("options"));
19988 if (eopt)
19990 Elf_Internal_Options option;
19992 offset = cnt = 0;
19993 while (offset <= sect->sh_size - sizeof (* eopt))
19995 Elf_External_Options * eoption;
19996 unsigned int optsize;
19998 eoption = (Elf_External_Options *) ((char *) eopt + offset);
20000 optsize = BYTE_GET (eoption->size);
20002 /* PR 17531: file: ffa0fa3b. */
20003 if (optsize < sizeof (* eopt)
20004 || optsize > sect->sh_size - offset)
20006 error (_("Invalid size (%u) for MIPS option\n"),
20007 optsize);
20008 free (eopt);
20009 return false;
20011 offset += optsize;
20012 ++cnt;
20015 printf (ngettext ("\nSection '%s' contains %d entry:\n",
20016 "\nSection '%s' contains %d entries:\n",
20017 cnt),
20018 printable_section_name (filedata, sect), cnt);
20020 offset = 0;
20021 while (cnt-- > 0)
20023 size_t len;
20024 Elf_External_Options * eoption;
20026 eoption = (Elf_External_Options *) ((char *) eopt + offset);
20028 option.kind = BYTE_GET (eoption->kind);
20029 option.size = BYTE_GET (eoption->size);
20030 option.section = BYTE_GET (eoption->section);
20031 option.info = BYTE_GET (eoption->info);
20033 switch (option.kind)
20035 case ODK_NULL:
20036 /* This shouldn't happen. */
20037 printf (" NULL %" PRId16 " %" PRIx32,
20038 option.section, option.info);
20039 break;
20041 case ODK_REGINFO:
20042 printf (" REGINFO ");
20043 if (filedata->file_header.e_machine == EM_MIPS)
20045 Elf32_External_RegInfo * ereg;
20046 Elf32_RegInfo reginfo;
20048 /* 32bit form. */
20049 if (option.size < (sizeof (Elf_External_Options)
20050 + sizeof (Elf32_External_RegInfo)))
20052 printf (_("<corrupt>\n"));
20053 error (_("Truncated MIPS REGINFO option\n"));
20054 cnt = 0;
20055 break;
20058 ereg = (Elf32_External_RegInfo *) (eoption + 1);
20060 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
20061 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
20062 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
20063 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
20064 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
20065 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
20067 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
20068 reginfo.ri_gprmask, reginfo.ri_gp_value);
20069 printf (" "
20070 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
20071 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
20072 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
20073 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
20075 else
20077 /* 64 bit form. */
20078 Elf64_External_RegInfo * ereg;
20079 Elf64_Internal_RegInfo reginfo;
20081 if (option.size < (sizeof (Elf_External_Options)
20082 + sizeof (Elf64_External_RegInfo)))
20084 printf (_("<corrupt>\n"));
20085 error (_("Truncated MIPS REGINFO option\n"));
20086 cnt = 0;
20087 break;
20090 ereg = (Elf64_External_RegInfo *) (eoption + 1);
20091 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
20092 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
20093 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
20094 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
20095 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
20096 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
20098 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
20099 reginfo.ri_gprmask, reginfo.ri_gp_value);
20100 printf (" "
20101 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
20102 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
20103 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
20104 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
20106 offset += option.size;
20107 continue;
20109 case ODK_EXCEPTIONS:
20110 fputs (" EXCEPTIONS fpe_min(", stdout);
20111 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
20112 fputs (") fpe_max(", stdout);
20113 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
20114 fputs (")", stdout);
20116 if (option.info & OEX_PAGE0)
20117 fputs (" PAGE0", stdout);
20118 if (option.info & OEX_SMM)
20119 fputs (" SMM", stdout);
20120 if (option.info & OEX_FPDBUG)
20121 fputs (" FPDBUG", stdout);
20122 if (option.info & OEX_DISMISS)
20123 fputs (" DISMISS", stdout);
20124 break;
20126 case ODK_PAD:
20127 fputs (" PAD ", stdout);
20128 if (option.info & OPAD_PREFIX)
20129 fputs (" PREFIX", stdout);
20130 if (option.info & OPAD_POSTFIX)
20131 fputs (" POSTFIX", stdout);
20132 if (option.info & OPAD_SYMBOL)
20133 fputs (" SYMBOL", stdout);
20134 break;
20136 case ODK_HWPATCH:
20137 fputs (" HWPATCH ", stdout);
20138 if (option.info & OHW_R4KEOP)
20139 fputs (" R4KEOP", stdout);
20140 if (option.info & OHW_R8KPFETCH)
20141 fputs (" R8KPFETCH", stdout);
20142 if (option.info & OHW_R5KEOP)
20143 fputs (" R5KEOP", stdout);
20144 if (option.info & OHW_R5KCVTL)
20145 fputs (" R5KCVTL", stdout);
20146 break;
20148 case ODK_FILL:
20149 fputs (" FILL ", stdout);
20150 /* XXX Print content of info word? */
20151 break;
20153 case ODK_TAGS:
20154 fputs (" TAGS ", stdout);
20155 /* XXX Print content of info word? */
20156 break;
20158 case ODK_HWAND:
20159 fputs (" HWAND ", stdout);
20160 if (option.info & OHWA0_R4KEOP_CHECKED)
20161 fputs (" R4KEOP_CHECKED", stdout);
20162 if (option.info & OHWA0_R4KEOP_CLEAN)
20163 fputs (" R4KEOP_CLEAN", stdout);
20164 break;
20166 case ODK_HWOR:
20167 fputs (" HWOR ", stdout);
20168 if (option.info & OHWA0_R4KEOP_CHECKED)
20169 fputs (" R4KEOP_CHECKED", stdout);
20170 if (option.info & OHWA0_R4KEOP_CLEAN)
20171 fputs (" R4KEOP_CLEAN", stdout);
20172 break;
20174 case ODK_GP_GROUP:
20175 printf (" GP_GROUP %#06x self-contained %#06x",
20176 option.info & OGP_GROUP,
20177 (option.info & OGP_SELF) >> 16);
20178 break;
20180 case ODK_IDENT:
20181 printf (" IDENT %#06x self-contained %#06x",
20182 option.info & OGP_GROUP,
20183 (option.info & OGP_SELF) >> 16);
20184 break;
20186 default:
20187 /* This shouldn't happen. */
20188 printf (" %3d ??? %" PRId16 " %" PRIx32,
20189 option.kind, option.section, option.info);
20190 break;
20193 len = sizeof (* eopt);
20194 while (len < option.size)
20196 unsigned char datum = *((unsigned char *) eoption + len);
20198 if (ISPRINT (datum))
20199 printf ("%c", datum);
20200 else
20201 printf ("\\%03o", datum);
20202 len ++;
20204 fputs ("\n", stdout);
20206 offset += option.size;
20208 free (eopt);
20210 else
20211 res = false;
20214 if (conflicts_offset != 0 && conflictsno != 0)
20216 Elf32_Conflict * iconf;
20217 size_t cnt;
20219 if (filedata->dynamic_symbols == NULL)
20221 error (_("conflict list found without a dynamic symbol table\n"));
20222 return false;
20225 /* PR 21345 - print a slightly more helpful error message
20226 if we are sure that the cmalloc will fail. */
20227 if (conflictsno > filedata->file_size / sizeof (* iconf))
20229 error (_("Overlarge number of conflicts detected: %zx\n"),
20230 conflictsno);
20231 return false;
20234 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
20235 if (iconf == NULL)
20237 error (_("Out of memory allocating space for dynamic conflicts\n"));
20238 return false;
20241 if (is_32bit_elf)
20243 Elf32_External_Conflict * econf32;
20245 econf32 = (Elf32_External_Conflict *)
20246 get_data (NULL, filedata, conflicts_offset,
20247 sizeof (*econf32), conflictsno, _("conflict"));
20248 if (!econf32)
20250 free (iconf);
20251 return false;
20254 for (cnt = 0; cnt < conflictsno; ++cnt)
20255 iconf[cnt] = BYTE_GET (econf32[cnt]);
20257 free (econf32);
20259 else
20261 Elf64_External_Conflict * econf64;
20263 econf64 = (Elf64_External_Conflict *)
20264 get_data (NULL, filedata, conflicts_offset,
20265 sizeof (*econf64), conflictsno, _("conflict"));
20266 if (!econf64)
20268 free (iconf);
20269 return false;
20272 for (cnt = 0; cnt < conflictsno; ++cnt)
20273 iconf[cnt] = BYTE_GET (econf64[cnt]);
20275 free (econf64);
20278 printf (ngettext ("\nSection '.conflict' contains %zu entry:\n",
20279 "\nSection '.conflict' contains %zu entries:\n",
20280 conflictsno),
20281 conflictsno);
20282 puts (_(" Num: Index Value Name"));
20284 for (cnt = 0; cnt < conflictsno; ++cnt)
20286 printf ("%5zu: %8lu ", cnt, iconf[cnt]);
20288 if (iconf[cnt] >= filedata->num_dynamic_syms)
20289 printf (_("<corrupt symbol index>"));
20290 else
20292 Elf_Internal_Sym * psym;
20294 psym = & filedata->dynamic_symbols[iconf[cnt]];
20295 print_vma (psym->st_value, FULL_HEX);
20296 putchar (' ');
20297 if (valid_dynamic_name (filedata, psym->st_name))
20298 print_symbol_name (25, get_dynamic_name (filedata, psym->st_name));
20299 else
20300 printf (_("<corrupt: %14ld>"), psym->st_name);
20302 putchar ('\n');
20305 free (iconf);
20308 if (pltgot != 0 && local_gotno != 0)
20310 uint64_t ent, local_end, global_end;
20311 size_t i, offset;
20312 unsigned char * data;
20313 unsigned char * data_end;
20314 int addr_size;
20316 ent = pltgot;
20317 addr_size = (is_32bit_elf ? 4 : 8);
20318 local_end = pltgot + local_gotno * addr_size;
20320 /* PR binutils/17533 file: 012-111227-0.004 */
20321 if (symtabno < gotsym)
20323 error (_("The GOT symbol offset (%" PRIu64
20324 ") is greater than the symbol table size (%" PRIu64 ")\n"),
20325 gotsym, symtabno);
20326 return false;
20329 global_end = local_end + (symtabno - gotsym) * addr_size;
20330 /* PR 17531: file: 54c91a34. */
20331 if (global_end < local_end)
20333 error (_("Too many GOT symbols: %" PRIu64 "\n"), symtabno);
20334 return false;
20337 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
20338 data = (unsigned char *) get_data (NULL, filedata, offset,
20339 global_end - pltgot, 1,
20340 _("Global Offset Table data"));
20341 /* PR 12855: Null data is handled gracefully throughout. */
20342 data_end = data + (global_end - pltgot);
20344 printf (_("\nPrimary GOT:\n"));
20345 printf (_(" Canonical gp value: "));
20346 print_vma (pltgot + 0x7ff0, LONG_HEX);
20347 printf ("\n\n");
20349 printf (_(" Reserved entries:\n"));
20350 printf (_(" %*s %10s %*s Purpose\n"),
20351 addr_size * 2, _("Address"), _("Access"),
20352 addr_size * 2, _("Initial"));
20353 ent = print_mips_got_entry (data, pltgot, ent, data_end);
20354 printf (_(" Lazy resolver\n"));
20355 if (ent == (uint64_t) -1)
20356 goto got_print_fail;
20358 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
20359 This entry will be used by some runtime loaders, to store the
20360 module pointer. Otherwise this is an ordinary local entry.
20361 PR 21344: Check for the entry being fully available before
20362 fetching it. */
20363 if (data
20364 && data + ent - pltgot + addr_size <= data_end
20365 && (byte_get (data + ent - pltgot, addr_size)
20366 >> (addr_size * 8 - 1)) != 0)
20368 ent = print_mips_got_entry (data, pltgot, ent, data_end);
20369 printf (_(" Module pointer (GNU extension)\n"));
20370 if (ent == (uint64_t) -1)
20371 goto got_print_fail;
20373 printf ("\n");
20375 if (data != NULL && ent < local_end)
20377 printf (_(" Local entries:\n"));
20378 printf (" %*s %10s %*s\n",
20379 addr_size * 2, _("Address"), _("Access"),
20380 addr_size * 2, _("Initial"));
20381 while (ent < local_end)
20383 ent = print_mips_got_entry (data, pltgot, ent, data_end);
20384 printf ("\n");
20385 if (ent == (uint64_t) -1)
20386 goto got_print_fail;
20388 printf ("\n");
20391 if (data != NULL && gotsym < symtabno)
20393 int sym_width;
20395 printf (_(" Global entries:\n"));
20396 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
20397 addr_size * 2, _("Address"),
20398 _("Access"),
20399 addr_size * 2, _("Initial"),
20400 addr_size * 2, _("Sym.Val."),
20401 _("Type"),
20402 /* Note for translators: "Ndx" = abbreviated form of "Index". */
20403 _("Ndx"), _("Name"));
20405 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
20407 for (i = gotsym; i < symtabno; i++)
20409 ent = print_mips_got_entry (data, pltgot, ent, data_end);
20410 printf (" ");
20412 if (filedata->dynamic_symbols == NULL)
20413 printf (_("<no dynamic symbols>"));
20414 else if (i < filedata->num_dynamic_syms)
20416 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
20418 print_vma (psym->st_value, LONG_HEX);
20419 printf (" %-7s ", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
20421 bool is_special;
20422 const char * s = printable_section_name_from_index (filedata, psym->st_shndx, & is_special);
20423 if (is_special)
20424 printf ("%3s ", s);
20425 else
20426 printf ("%3u ", psym->st_shndx);
20428 if (valid_dynamic_name (filedata, psym->st_name))
20429 print_symbol_name (sym_width,
20430 get_dynamic_name (filedata, psym->st_name));
20431 else
20432 printf (_("<corrupt: %14ld>"), psym->st_name);
20434 else
20435 printf (_("<symbol index %zu exceeds number of dynamic symbols>"),
20438 printf ("\n");
20439 if (ent == (uint64_t) -1)
20440 break;
20442 printf ("\n");
20445 got_print_fail:
20446 free (data);
20449 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
20451 uint64_t ent, end;
20452 uint64_t offset, rel_offset;
20453 uint64_t count, i;
20454 unsigned char * data;
20455 int addr_size, sym_width;
20456 Elf_Internal_Rela * rels;
20458 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
20459 if (pltrel == DT_RELA)
20461 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
20462 return false;
20464 else
20466 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
20467 return false;
20470 ent = mips_pltgot;
20471 addr_size = (is_32bit_elf ? 4 : 8);
20472 end = mips_pltgot + (2 + count) * addr_size;
20474 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
20475 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
20476 1, _("Procedure Linkage Table data"));
20477 if (data == NULL)
20479 free (rels);
20480 return false;
20483 printf ("\nPLT GOT:\n\n");
20484 printf (_(" Reserved entries:\n"));
20485 printf (_(" %*s %*s Purpose\n"),
20486 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
20487 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
20488 printf (_(" PLT lazy resolver\n"));
20489 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
20490 printf (_(" Module pointer\n"));
20491 printf ("\n");
20493 printf (_(" Entries:\n"));
20494 printf (" %*s %*s %*s %-7s %3s %s\n",
20495 addr_size * 2, _("Address"),
20496 addr_size * 2, _("Initial"),
20497 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
20498 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
20499 for (i = 0; i < count; i++)
20501 uint64_t idx = get_reloc_symindex (rels[i].r_info);
20503 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
20504 printf (" ");
20506 if (idx >= filedata->num_dynamic_syms)
20507 printf (_("<corrupt symbol index: %" PRIu64 ">"), idx);
20508 else
20510 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
20512 print_vma (psym->st_value, LONG_HEX);
20513 printf (" %-7s %3s ",
20514 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
20515 printable_section_name_from_index (filedata, psym->st_shndx, NULL));
20516 if (valid_dynamic_name (filedata, psym->st_name))
20517 print_symbol_name (sym_width,
20518 get_dynamic_name (filedata, psym->st_name));
20519 else
20520 printf (_("<corrupt: %14ld>"), psym->st_name);
20522 printf ("\n");
20524 printf ("\n");
20526 free (data);
20527 free (rels);
20530 return res;
20533 static bool
20534 process_nds32_specific (Filedata * filedata)
20536 Elf_Internal_Shdr *sect = NULL;
20538 sect = find_section (filedata, ".nds32_e_flags");
20539 if (sect != NULL && sect->sh_size >= 4)
20541 unsigned char *buf;
20542 unsigned int flag;
20544 printf ("\nNDS32 elf flags section:\n");
20545 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
20546 _("NDS32 elf flags section"));
20548 if (buf == NULL)
20549 return false;
20551 flag = byte_get (buf, 4);
20552 free (buf);
20553 switch (flag & 0x3)
20555 case 0:
20556 printf ("(VEC_SIZE):\tNo entry.\n");
20557 break;
20558 case 1:
20559 printf ("(VEC_SIZE):\t4 bytes\n");
20560 break;
20561 case 2:
20562 printf ("(VEC_SIZE):\t16 bytes\n");
20563 break;
20564 case 3:
20565 printf ("(VEC_SIZE):\treserved\n");
20566 break;
20570 return true;
20573 static bool
20574 process_gnu_liblist (Filedata * filedata)
20576 Elf_Internal_Shdr * section;
20577 Elf_Internal_Shdr * string_sec;
20578 Elf32_External_Lib * elib;
20579 char * strtab;
20580 size_t strtab_size;
20581 size_t cnt;
20582 uint64_t num_liblist;
20583 unsigned i;
20584 bool res = true;
20586 if (! do_arch)
20587 return true;
20589 for (i = 0, section = filedata->section_headers;
20590 i < filedata->file_header.e_shnum;
20591 i++, section++)
20593 switch (section->sh_type)
20595 case SHT_GNU_LIBLIST:
20596 if (section->sh_link >= filedata->file_header.e_shnum)
20597 break;
20599 elib = (Elf32_External_Lib *)
20600 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
20601 _("liblist section data"));
20603 if (elib == NULL)
20605 res = false;
20606 break;
20609 string_sec = filedata->section_headers + section->sh_link;
20610 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
20611 string_sec->sh_size,
20612 _("liblist string table"));
20613 if (strtab == NULL
20614 || section->sh_entsize != sizeof (Elf32_External_Lib))
20616 free (elib);
20617 free (strtab);
20618 res = false;
20619 break;
20621 strtab_size = string_sec->sh_size;
20623 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
20624 printf (ngettext ("\nLibrary list section '%s' contains %" PRIu64
20625 " entries:\n",
20626 "\nLibrary list section '%s' contains %" PRIu64
20627 " entries:\n",
20628 num_liblist),
20629 printable_section_name (filedata, section),
20630 num_liblist);
20632 puts (_(" Library Time Stamp Checksum Version Flags"));
20634 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
20635 ++cnt)
20637 Elf32_Lib liblist;
20638 time_t atime;
20639 char timebuf[128];
20640 struct tm * tmp;
20642 liblist.l_name = BYTE_GET (elib[cnt].l_name);
20643 atime = BYTE_GET (elib[cnt].l_time_stamp);
20644 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
20645 liblist.l_version = BYTE_GET (elib[cnt].l_version);
20646 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
20648 tmp = gmtime (&atime);
20649 snprintf (timebuf, sizeof (timebuf),
20650 "%04u-%02u-%02uT%02u:%02u:%02u",
20651 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
20652 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
20654 printf ("%3zu: ", cnt);
20655 if (do_wide)
20656 printf ("%-20s", liblist.l_name < strtab_size
20657 ? strtab + liblist.l_name : _("<corrupt>"));
20658 else
20659 printf ("%-20.20s", liblist.l_name < strtab_size
20660 ? strtab + liblist.l_name : _("<corrupt>"));
20661 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
20662 liblist.l_version, liblist.l_flags);
20665 free (elib);
20666 free (strtab);
20670 return res;
20673 static const char *
20674 get_note_type (Filedata * filedata, unsigned e_type)
20676 static char buff[64];
20678 if (filedata->file_header.e_type == ET_CORE)
20679 switch (e_type)
20681 case NT_AUXV:
20682 return _("NT_AUXV (auxiliary vector)");
20683 case NT_PRSTATUS:
20684 return _("NT_PRSTATUS (prstatus structure)");
20685 case NT_FPREGSET:
20686 return _("NT_FPREGSET (floating point registers)");
20687 case NT_PRPSINFO:
20688 return _("NT_PRPSINFO (prpsinfo structure)");
20689 case NT_TASKSTRUCT:
20690 return _("NT_TASKSTRUCT (task structure)");
20691 case NT_GDB_TDESC:
20692 return _("NT_GDB_TDESC (GDB XML target description)");
20693 case NT_PRXFPREG:
20694 return _("NT_PRXFPREG (user_xfpregs structure)");
20695 case NT_PPC_VMX:
20696 return _("NT_PPC_VMX (ppc Altivec registers)");
20697 case NT_PPC_VSX:
20698 return _("NT_PPC_VSX (ppc VSX registers)");
20699 case NT_PPC_TAR:
20700 return _("NT_PPC_TAR (ppc TAR register)");
20701 case NT_PPC_PPR:
20702 return _("NT_PPC_PPR (ppc PPR register)");
20703 case NT_PPC_DSCR:
20704 return _("NT_PPC_DSCR (ppc DSCR register)");
20705 case NT_PPC_EBB:
20706 return _("NT_PPC_EBB (ppc EBB registers)");
20707 case NT_PPC_PMU:
20708 return _("NT_PPC_PMU (ppc PMU registers)");
20709 case NT_PPC_TM_CGPR:
20710 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
20711 case NT_PPC_TM_CFPR:
20712 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
20713 case NT_PPC_TM_CVMX:
20714 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
20715 case NT_PPC_TM_CVSX:
20716 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
20717 case NT_PPC_TM_SPR:
20718 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
20719 case NT_PPC_TM_CTAR:
20720 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
20721 case NT_PPC_TM_CPPR:
20722 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
20723 case NT_PPC_TM_CDSCR:
20724 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
20725 case NT_386_TLS:
20726 return _("NT_386_TLS (x86 TLS information)");
20727 case NT_386_IOPERM:
20728 return _("NT_386_IOPERM (x86 I/O permissions)");
20729 case NT_X86_XSTATE:
20730 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
20731 case NT_X86_CET:
20732 return _("NT_X86_CET (x86 CET state)");
20733 case NT_X86_SHSTK:
20734 return _("NT_X86_SHSTK (x86 SHSTK state)");
20735 case NT_S390_HIGH_GPRS:
20736 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
20737 case NT_S390_TIMER:
20738 return _("NT_S390_TIMER (s390 timer register)");
20739 case NT_S390_TODCMP:
20740 return _("NT_S390_TODCMP (s390 TOD comparator register)");
20741 case NT_S390_TODPREG:
20742 return _("NT_S390_TODPREG (s390 TOD programmable register)");
20743 case NT_S390_CTRS:
20744 return _("NT_S390_CTRS (s390 control registers)");
20745 case NT_S390_PREFIX:
20746 return _("NT_S390_PREFIX (s390 prefix register)");
20747 case NT_S390_LAST_BREAK:
20748 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
20749 case NT_S390_SYSTEM_CALL:
20750 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
20751 case NT_S390_TDB:
20752 return _("NT_S390_TDB (s390 transaction diagnostic block)");
20753 case NT_S390_VXRS_LOW:
20754 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
20755 case NT_S390_VXRS_HIGH:
20756 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
20757 case NT_S390_GS_CB:
20758 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
20759 case NT_S390_GS_BC:
20760 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
20761 case NT_ARM_VFP:
20762 return _("NT_ARM_VFP (arm VFP registers)");
20763 case NT_ARM_TLS:
20764 return _("NT_ARM_TLS (AArch TLS registers)");
20765 case NT_ARM_HW_BREAK:
20766 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
20767 case NT_ARM_HW_WATCH:
20768 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
20769 case NT_ARM_SYSTEM_CALL:
20770 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
20771 case NT_ARM_SVE:
20772 return _("NT_ARM_SVE (AArch SVE registers)");
20773 case NT_ARM_PAC_MASK:
20774 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
20775 case NT_ARM_PACA_KEYS:
20776 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
20777 case NT_ARM_PACG_KEYS:
20778 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
20779 case NT_ARM_TAGGED_ADDR_CTRL:
20780 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
20781 case NT_ARM_SSVE:
20782 return _("NT_ARM_SSVE (AArch64 streaming SVE registers)");
20783 case NT_ARM_ZA:
20784 return _("NT_ARM_ZA (AArch64 SME ZA register)");
20785 case NT_ARM_ZT:
20786 return _("NT_ARM_ZT (AArch64 SME2 ZT registers)");
20787 case NT_ARM_PAC_ENABLED_KEYS:
20788 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
20789 case NT_ARC_V2:
20790 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
20791 case NT_RISCV_CSR:
20792 return _("NT_RISCV_CSR (RISC-V control and status registers)");
20793 case NT_PSTATUS:
20794 return _("NT_PSTATUS (pstatus structure)");
20795 case NT_FPREGS:
20796 return _("NT_FPREGS (floating point registers)");
20797 case NT_PSINFO:
20798 return _("NT_PSINFO (psinfo structure)");
20799 case NT_LWPSTATUS:
20800 return _("NT_LWPSTATUS (lwpstatus_t structure)");
20801 case NT_LWPSINFO:
20802 return _("NT_LWPSINFO (lwpsinfo_t structure)");
20803 case NT_WIN32PSTATUS:
20804 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
20805 case NT_SIGINFO:
20806 return _("NT_SIGINFO (siginfo_t data)");
20807 case NT_FILE:
20808 return _("NT_FILE (mapped files)");
20809 default:
20810 break;
20812 else
20813 switch (e_type)
20815 case NT_VERSION:
20816 return _("NT_VERSION (version)");
20817 case NT_ARCH:
20818 return _("NT_ARCH (architecture)");
20819 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
20820 return _("OPEN");
20821 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
20822 return _("func");
20823 case NT_GO_BUILDID:
20824 return _("GO BUILDID");
20825 case FDO_PACKAGING_METADATA:
20826 return _("FDO_PACKAGING_METADATA");
20827 case FDO_DLOPEN_METADATA:
20828 return _("FDO_DLOPEN_METADATA");
20829 default:
20830 break;
20833 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20834 return buff;
20837 static bool
20838 print_core_note (Elf_Internal_Note *pnote)
20840 unsigned int addr_size = is_32bit_elf ? 4 : 8;
20841 uint64_t count, page_size;
20842 unsigned char *descdata, *filenames, *descend;
20844 if (pnote->type != NT_FILE)
20846 if (do_wide)
20847 printf ("\n");
20848 return true;
20851 if (pnote->descsz < 2 * addr_size)
20853 error (_(" Malformed note - too short for header\n"));
20854 return false;
20857 descdata = (unsigned char *) pnote->descdata;
20858 descend = descdata + pnote->descsz;
20860 if (descdata[pnote->descsz - 1] != '\0')
20862 error (_(" Malformed note - does not end with \\0\n"));
20863 return false;
20866 count = byte_get (descdata, addr_size);
20867 descdata += addr_size;
20869 page_size = byte_get (descdata, addr_size);
20870 descdata += addr_size;
20872 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
20873 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
20875 error (_(" Malformed note - too short for supplied file count\n"));
20876 return false;
20879 printf (_(" Page size: "));
20880 print_vma (page_size, DEC);
20881 printf ("\n");
20883 printf (_(" %*s%*s%*s\n"),
20884 (int) (2 + 2 * addr_size), _("Start"),
20885 (int) (4 + 2 * addr_size), _("End"),
20886 (int) (4 + 2 * addr_size), _("Page Offset"));
20887 filenames = descdata + count * 3 * addr_size;
20888 while (count-- > 0)
20890 uint64_t start, end, file_ofs;
20892 if (filenames == descend)
20894 error (_(" Malformed note - filenames end too early\n"));
20895 return false;
20898 start = byte_get (descdata, addr_size);
20899 descdata += addr_size;
20900 end = byte_get (descdata, addr_size);
20901 descdata += addr_size;
20902 file_ofs = byte_get (descdata, addr_size);
20903 descdata += addr_size;
20905 printf (" ");
20906 print_vma (start, FULL_HEX);
20907 printf (" ");
20908 print_vma (end, FULL_HEX);
20909 printf (" ");
20910 print_vma (file_ofs, FULL_HEX);
20911 printf ("\n %s\n", filenames);
20913 filenames += 1 + strlen ((char *) filenames);
20916 return true;
20919 static const char *
20920 get_gnu_elf_note_type (unsigned e_type)
20922 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
20923 switch (e_type)
20925 case NT_GNU_ABI_TAG:
20926 return _("NT_GNU_ABI_TAG (ABI version tag)");
20927 case NT_GNU_HWCAP:
20928 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
20929 case NT_GNU_BUILD_ID:
20930 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
20931 case NT_GNU_GOLD_VERSION:
20932 return _("NT_GNU_GOLD_VERSION (gold version)");
20933 case NT_GNU_PROPERTY_TYPE_0:
20934 return _("NT_GNU_PROPERTY_TYPE_0");
20935 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
20936 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
20937 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
20938 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
20939 default:
20941 static char buff[64];
20943 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20944 return buff;
20949 static void
20950 decode_x86_compat_isa (unsigned int bitmask)
20952 while (bitmask)
20954 unsigned int bit = bitmask & (- bitmask);
20956 bitmask &= ~ bit;
20957 switch (bit)
20959 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
20960 printf ("i486");
20961 break;
20962 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
20963 printf ("586");
20964 break;
20965 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
20966 printf ("686");
20967 break;
20968 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
20969 printf ("SSE");
20970 break;
20971 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
20972 printf ("SSE2");
20973 break;
20974 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
20975 printf ("SSE3");
20976 break;
20977 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
20978 printf ("SSSE3");
20979 break;
20980 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
20981 printf ("SSE4_1");
20982 break;
20983 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
20984 printf ("SSE4_2");
20985 break;
20986 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
20987 printf ("AVX");
20988 break;
20989 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
20990 printf ("AVX2");
20991 break;
20992 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
20993 printf ("AVX512F");
20994 break;
20995 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
20996 printf ("AVX512CD");
20997 break;
20998 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
20999 printf ("AVX512ER");
21000 break;
21001 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
21002 printf ("AVX512PF");
21003 break;
21004 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
21005 printf ("AVX512VL");
21006 break;
21007 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
21008 printf ("AVX512DQ");
21009 break;
21010 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
21011 printf ("AVX512BW");
21012 break;
21013 default:
21014 printf (_("<unknown: %x>"), bit);
21015 break;
21017 if (bitmask)
21018 printf (", ");
21022 static void
21023 decode_x86_compat_2_isa (unsigned int bitmask)
21025 if (!bitmask)
21027 printf (_("<None>"));
21028 return;
21031 while (bitmask)
21033 unsigned int bit = bitmask & (- bitmask);
21035 bitmask &= ~ bit;
21036 switch (bit)
21038 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
21039 printf ("CMOV");
21040 break;
21041 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
21042 printf ("SSE");
21043 break;
21044 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
21045 printf ("SSE2");
21046 break;
21047 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
21048 printf ("SSE3");
21049 break;
21050 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
21051 printf ("SSSE3");
21052 break;
21053 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
21054 printf ("SSE4_1");
21055 break;
21056 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
21057 printf ("SSE4_2");
21058 break;
21059 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
21060 printf ("AVX");
21061 break;
21062 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
21063 printf ("AVX2");
21064 break;
21065 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
21066 printf ("FMA");
21067 break;
21068 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
21069 printf ("AVX512F");
21070 break;
21071 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
21072 printf ("AVX512CD");
21073 break;
21074 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
21075 printf ("AVX512ER");
21076 break;
21077 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
21078 printf ("AVX512PF");
21079 break;
21080 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
21081 printf ("AVX512VL");
21082 break;
21083 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
21084 printf ("AVX512DQ");
21085 break;
21086 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
21087 printf ("AVX512BW");
21088 break;
21089 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
21090 printf ("AVX512_4FMAPS");
21091 break;
21092 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
21093 printf ("AVX512_4VNNIW");
21094 break;
21095 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
21096 printf ("AVX512_BITALG");
21097 break;
21098 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
21099 printf ("AVX512_IFMA");
21100 break;
21101 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
21102 printf ("AVX512_VBMI");
21103 break;
21104 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
21105 printf ("AVX512_VBMI2");
21106 break;
21107 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
21108 printf ("AVX512_VNNI");
21109 break;
21110 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
21111 printf ("AVX512_BF16");
21112 break;
21113 default:
21114 printf (_("<unknown: %x>"), bit);
21115 break;
21117 if (bitmask)
21118 printf (", ");
21122 static const char *
21123 get_amdgpu_elf_note_type (unsigned int e_type)
21125 switch (e_type)
21127 case NT_AMDGPU_METADATA:
21128 return _("NT_AMDGPU_METADATA (code object metadata)");
21129 default:
21131 static char buf[64];
21132 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
21133 return buf;
21138 static void
21139 decode_x86_isa (unsigned int bitmask)
21141 while (bitmask)
21143 unsigned int bit = bitmask & (- bitmask);
21145 bitmask &= ~ bit;
21146 switch (bit)
21148 case GNU_PROPERTY_X86_ISA_1_BASELINE:
21149 printf ("x86-64-baseline");
21150 break;
21151 case GNU_PROPERTY_X86_ISA_1_V2:
21152 printf ("x86-64-v2");
21153 break;
21154 case GNU_PROPERTY_X86_ISA_1_V3:
21155 printf ("x86-64-v3");
21156 break;
21157 case GNU_PROPERTY_X86_ISA_1_V4:
21158 printf ("x86-64-v4");
21159 break;
21160 default:
21161 printf (_("<unknown: %x>"), bit);
21162 break;
21164 if (bitmask)
21165 printf (", ");
21169 static void
21170 decode_x86_feature_1 (unsigned int bitmask)
21172 if (!bitmask)
21174 printf (_("<None>"));
21175 return;
21178 while (bitmask)
21180 unsigned int bit = bitmask & (- bitmask);
21182 bitmask &= ~ bit;
21183 switch (bit)
21185 case GNU_PROPERTY_X86_FEATURE_1_IBT:
21186 printf ("IBT");
21187 break;
21188 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
21189 printf ("SHSTK");
21190 break;
21191 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
21192 printf ("LAM_U48");
21193 break;
21194 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
21195 printf ("LAM_U57");
21196 break;
21197 default:
21198 printf (_("<unknown: %x>"), bit);
21199 break;
21201 if (bitmask)
21202 printf (", ");
21206 static void
21207 decode_x86_feature_2 (unsigned int bitmask)
21209 if (!bitmask)
21211 printf (_("<None>"));
21212 return;
21215 while (bitmask)
21217 unsigned int bit = bitmask & (- bitmask);
21219 bitmask &= ~ bit;
21220 switch (bit)
21222 case GNU_PROPERTY_X86_FEATURE_2_X86:
21223 printf ("x86");
21224 break;
21225 case GNU_PROPERTY_X86_FEATURE_2_X87:
21226 printf ("x87");
21227 break;
21228 case GNU_PROPERTY_X86_FEATURE_2_MMX:
21229 printf ("MMX");
21230 break;
21231 case GNU_PROPERTY_X86_FEATURE_2_XMM:
21232 printf ("XMM");
21233 break;
21234 case GNU_PROPERTY_X86_FEATURE_2_YMM:
21235 printf ("YMM");
21236 break;
21237 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
21238 printf ("ZMM");
21239 break;
21240 case GNU_PROPERTY_X86_FEATURE_2_TMM:
21241 printf ("TMM");
21242 break;
21243 case GNU_PROPERTY_X86_FEATURE_2_MASK:
21244 printf ("MASK");
21245 break;
21246 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
21247 printf ("FXSR");
21248 break;
21249 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
21250 printf ("XSAVE");
21251 break;
21252 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
21253 printf ("XSAVEOPT");
21254 break;
21255 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
21256 printf ("XSAVEC");
21257 break;
21258 default:
21259 printf (_("<unknown: %x>"), bit);
21260 break;
21262 if (bitmask)
21263 printf (", ");
21267 static void
21268 decode_aarch64_feature_1_and (unsigned int bitmask)
21270 while (bitmask)
21272 unsigned int bit = bitmask & (- bitmask);
21274 bitmask &= ~ bit;
21275 switch (bit)
21277 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
21278 printf ("BTI");
21279 break;
21281 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
21282 printf ("PAC");
21283 break;
21285 case GNU_PROPERTY_AARCH64_FEATURE_1_GCS:
21286 printf ("GCS");
21287 break;
21289 default:
21290 printf (_("<unknown: %x>"), bit);
21291 break;
21293 if (bitmask)
21294 printf (", ");
21298 static void
21299 decode_1_needed (unsigned int bitmask)
21301 while (bitmask)
21303 unsigned int bit = bitmask & (- bitmask);
21305 bitmask &= ~ bit;
21306 switch (bit)
21308 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
21309 printf ("indirect external access");
21310 break;
21311 default:
21312 printf (_("<unknown: %x>"), bit);
21313 break;
21315 if (bitmask)
21316 printf (", ");
21320 static void
21321 print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
21323 unsigned char * ptr = (unsigned char *) pnote->descdata;
21324 unsigned char * ptr_end = ptr + pnote->descsz;
21325 unsigned int size = is_32bit_elf ? 4 : 8;
21327 printf (_(" Properties: "));
21329 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
21331 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
21332 return;
21335 while (ptr < ptr_end)
21337 unsigned int j;
21338 unsigned int type;
21339 unsigned int datasz;
21341 if ((size_t) (ptr_end - ptr) < 8)
21343 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
21344 break;
21347 type = byte_get (ptr, 4);
21348 datasz = byte_get (ptr + 4, 4);
21350 ptr += 8;
21352 if (datasz > (size_t) (ptr_end - ptr))
21354 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
21355 type, datasz);
21356 break;
21359 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
21361 if (filedata->file_header.e_machine == EM_X86_64
21362 || filedata->file_header.e_machine == EM_IAMCU
21363 || filedata->file_header.e_machine == EM_386)
21365 unsigned int bitmask;
21367 if (datasz == 4)
21368 bitmask = byte_get (ptr, 4);
21369 else
21370 bitmask = 0;
21372 switch (type)
21374 case GNU_PROPERTY_X86_ISA_1_USED:
21375 if (datasz != 4)
21376 printf (_("x86 ISA used: <corrupt length: %#x> "),
21377 datasz);
21378 else
21380 printf ("x86 ISA used: ");
21381 decode_x86_isa (bitmask);
21383 goto next;
21385 case GNU_PROPERTY_X86_ISA_1_NEEDED:
21386 if (datasz != 4)
21387 printf (_("x86 ISA needed: <corrupt length: %#x> "),
21388 datasz);
21389 else
21391 printf ("x86 ISA needed: ");
21392 decode_x86_isa (bitmask);
21394 goto next;
21396 case GNU_PROPERTY_X86_FEATURE_1_AND:
21397 if (datasz != 4)
21398 printf (_("x86 feature: <corrupt length: %#x> "),
21399 datasz);
21400 else
21402 printf ("x86 feature: ");
21403 decode_x86_feature_1 (bitmask);
21405 goto next;
21407 case GNU_PROPERTY_X86_FEATURE_2_USED:
21408 if (datasz != 4)
21409 printf (_("x86 feature used: <corrupt length: %#x> "),
21410 datasz);
21411 else
21413 printf ("x86 feature used: ");
21414 decode_x86_feature_2 (bitmask);
21416 goto next;
21418 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
21419 if (datasz != 4)
21420 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
21421 else
21423 printf ("x86 feature needed: ");
21424 decode_x86_feature_2 (bitmask);
21426 goto next;
21428 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
21429 if (datasz != 4)
21430 printf (_("x86 ISA used: <corrupt length: %#x> "),
21431 datasz);
21432 else
21434 printf ("x86 ISA used: ");
21435 decode_x86_compat_isa (bitmask);
21437 goto next;
21439 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
21440 if (datasz != 4)
21441 printf (_("x86 ISA needed: <corrupt length: %#x> "),
21442 datasz);
21443 else
21445 printf ("x86 ISA needed: ");
21446 decode_x86_compat_isa (bitmask);
21448 goto next;
21450 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
21451 if (datasz != 4)
21452 printf (_("x86 ISA used: <corrupt length: %#x> "),
21453 datasz);
21454 else
21456 printf ("x86 ISA used: ");
21457 decode_x86_compat_2_isa (bitmask);
21459 goto next;
21461 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
21462 if (datasz != 4)
21463 printf (_("x86 ISA needed: <corrupt length: %#x> "),
21464 datasz);
21465 else
21467 printf ("x86 ISA needed: ");
21468 decode_x86_compat_2_isa (bitmask);
21470 goto next;
21472 default:
21473 break;
21476 else if (filedata->file_header.e_machine == EM_AARCH64)
21478 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
21480 printf ("AArch64 feature: ");
21481 if (datasz != 4)
21482 printf (_("<corrupt length: %#x> "), datasz);
21483 else
21484 decode_aarch64_feature_1_and (byte_get (ptr, 4));
21485 goto next;
21489 else
21491 switch (type)
21493 case GNU_PROPERTY_STACK_SIZE:
21494 printf (_("stack size: "));
21495 if (datasz != size)
21496 printf (_("<corrupt length: %#x> "), datasz);
21497 else
21498 printf ("%#" PRIx64, byte_get (ptr, size));
21499 goto next;
21501 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
21502 printf ("no copy on protected ");
21503 if (datasz)
21504 printf (_("<corrupt length: %#x> "), datasz);
21505 goto next;
21507 case GNU_PROPERTY_MEMORY_SEAL:
21508 printf ("memory seal ");
21509 if (datasz)
21510 printf (_("<corrupt length: %#x> "), datasz);
21511 goto next;
21513 default:
21514 if ((type >= GNU_PROPERTY_UINT32_AND_LO
21515 && type <= GNU_PROPERTY_UINT32_AND_HI)
21516 || (type >= GNU_PROPERTY_UINT32_OR_LO
21517 && type <= GNU_PROPERTY_UINT32_OR_HI))
21519 switch (type)
21521 case GNU_PROPERTY_1_NEEDED:
21522 if (datasz != 4)
21523 printf (_("1_needed: <corrupt length: %#x> "),
21524 datasz);
21525 else
21527 unsigned int bitmask = byte_get (ptr, 4);
21528 printf ("1_needed: ");
21529 decode_1_needed (bitmask);
21531 goto next;
21533 default:
21534 break;
21536 if (type <= GNU_PROPERTY_UINT32_AND_HI)
21537 printf (_("UINT32_AND (%#x): "), type);
21538 else
21539 printf (_("UINT32_OR (%#x): "), type);
21540 if (datasz != 4)
21541 printf (_("<corrupt length: %#x> "), datasz);
21542 else
21543 printf ("%#x", (unsigned int) byte_get (ptr, 4));
21544 goto next;
21546 break;
21550 if (type < GNU_PROPERTY_LOPROC)
21551 printf (_("<unknown type %#x data: "), type);
21552 else if (type < GNU_PROPERTY_LOUSER)
21553 printf (_("<processor-specific type %#x data: "), type);
21554 else
21555 printf (_("<application-specific type %#x data: "), type);
21556 for (j = 0; j < datasz; ++j)
21557 printf ("%02x ", ptr[j] & 0xff);
21558 printf (">");
21560 next:
21561 ptr += ((datasz + (size - 1)) & ~ (size - 1));
21562 if (ptr == ptr_end)
21563 break;
21565 if (do_wide)
21566 printf (", ");
21567 else
21568 printf ("\n\t");
21571 printf ("\n");
21574 static bool
21575 print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
21577 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
21578 switch (pnote->type)
21580 case NT_GNU_BUILD_ID:
21582 size_t i;
21584 printf (_(" Build ID: "));
21585 for (i = 0; i < pnote->descsz; ++i)
21586 printf ("%02x", pnote->descdata[i] & 0xff);
21587 printf ("\n");
21589 break;
21591 case NT_GNU_ABI_TAG:
21593 unsigned int os, major, minor, subminor;
21594 const char *osname;
21596 /* PR 17531: file: 030-599401-0.004. */
21597 if (pnote->descsz < 16)
21599 printf (_(" <corrupt GNU_ABI_TAG>\n"));
21600 break;
21603 os = byte_get ((unsigned char *) pnote->descdata, 4);
21604 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
21605 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
21606 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
21608 switch (os)
21610 case GNU_ABI_TAG_LINUX:
21611 osname = "Linux";
21612 break;
21613 case GNU_ABI_TAG_HURD:
21614 osname = "Hurd";
21615 break;
21616 case GNU_ABI_TAG_SOLARIS:
21617 osname = "Solaris";
21618 break;
21619 case GNU_ABI_TAG_FREEBSD:
21620 osname = "FreeBSD";
21621 break;
21622 case GNU_ABI_TAG_NETBSD:
21623 osname = "NetBSD";
21624 break;
21625 case GNU_ABI_TAG_SYLLABLE:
21626 osname = "Syllable";
21627 break;
21628 case GNU_ABI_TAG_NACL:
21629 osname = "NaCl";
21630 break;
21631 default:
21632 osname = "Unknown";
21633 break;
21636 printf (_(" OS: %s, ABI: %d.%d.%d\n"), osname,
21637 major, minor, subminor);
21639 break;
21641 case NT_GNU_GOLD_VERSION:
21643 size_t i;
21645 printf (_(" Version: "));
21646 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
21647 printf ("%c", pnote->descdata[i]);
21648 printf ("\n");
21650 break;
21652 case NT_GNU_HWCAP:
21654 unsigned int num_entries, mask;
21656 /* Hardware capabilities information. Word 0 is the number of entries.
21657 Word 1 is a bitmask of enabled entries. The rest of the descriptor
21658 is a series of entries, where each entry is a single byte followed
21659 by a nul terminated string. The byte gives the bit number to test
21660 if enabled in the bitmask. */
21661 printf (_(" Hardware Capabilities: "));
21662 if (pnote->descsz < 8)
21664 error (_("<corrupt GNU_HWCAP>\n"));
21665 return false;
21667 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
21668 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
21669 printf (_("num entries: %d, enabled mask: %x\n"), num_entries, mask);
21670 /* FIXME: Add code to display the entries... */
21672 break;
21674 case NT_GNU_PROPERTY_TYPE_0:
21675 print_gnu_property_note (filedata, pnote);
21676 break;
21678 default:
21679 /* Handle unrecognised types. An error message should have already been
21680 created by get_gnu_elf_note_type(), so all that we need to do is to
21681 display the data. */
21683 size_t i;
21685 printf (_(" Description data: "));
21686 for (i = 0; i < pnote->descsz; ++i)
21687 printf ("%02x ", pnote->descdata[i] & 0xff);
21688 printf ("\n");
21690 break;
21693 return true;
21696 static const char *
21697 get_v850_elf_note_type (enum v850_notes n_type)
21699 static char buff[64];
21701 switch (n_type)
21703 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
21704 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
21705 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
21706 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
21707 case V850_NOTE_CACHE_INFO: return _("Use of cache");
21708 case V850_NOTE_MMU_INFO: return _("Use of MMU");
21709 default:
21710 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
21711 return buff;
21715 static bool
21716 print_v850_note (Elf_Internal_Note * pnote)
21718 unsigned int val;
21720 if (pnote->descsz != 4)
21721 return false;
21723 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
21725 if (val == 0)
21727 printf (_("not set\n"));
21728 return true;
21731 switch (pnote->type)
21733 case V850_NOTE_ALIGNMENT:
21734 switch (val)
21736 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
21737 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
21739 break;
21741 case V850_NOTE_DATA_SIZE:
21742 switch (val)
21744 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
21745 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
21747 break;
21749 case V850_NOTE_FPU_INFO:
21750 switch (val)
21752 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
21753 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
21755 break;
21757 case V850_NOTE_MMU_INFO:
21758 case V850_NOTE_CACHE_INFO:
21759 case V850_NOTE_SIMD_INFO:
21760 if (val == EF_RH850_SIMD)
21762 printf (_("yes\n"));
21763 return true;
21765 break;
21767 default:
21768 /* An 'unknown note type' message will already have been displayed. */
21769 break;
21772 printf (_("unknown value: %x\n"), val);
21773 return false;
21776 static bool
21777 process_netbsd_elf_note (Elf_Internal_Note * pnote)
21779 unsigned int version;
21781 switch (pnote->type)
21783 case NT_NETBSD_IDENT:
21784 if (pnote->descsz < 1)
21785 break;
21786 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21787 if ((version / 10000) % 100)
21788 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
21789 version, version / 100000000, (version / 1000000) % 100,
21790 (version / 10000) % 100 > 26 ? "Z" : "",
21791 'A' + (version / 10000) % 26);
21792 else
21793 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
21794 version, version / 100000000, (version / 1000000) % 100,
21795 (version / 100) % 100);
21796 return true;
21798 case NT_NETBSD_MARCH:
21799 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
21800 pnote->descdata);
21801 return true;
21803 case NT_NETBSD_PAX:
21804 if (pnote->descsz < 1)
21805 break;
21806 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21807 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
21808 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
21809 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
21810 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
21811 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
21812 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
21813 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
21814 return true;
21817 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
21818 pnote->descsz, pnote->type);
21819 return false;
21822 static const char *
21823 get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
21825 switch (e_type)
21827 case NT_FREEBSD_THRMISC:
21828 return _("NT_THRMISC (thrmisc structure)");
21829 case NT_FREEBSD_PROCSTAT_PROC:
21830 return _("NT_PROCSTAT_PROC (proc data)");
21831 case NT_FREEBSD_PROCSTAT_FILES:
21832 return _("NT_PROCSTAT_FILES (files data)");
21833 case NT_FREEBSD_PROCSTAT_VMMAP:
21834 return _("NT_PROCSTAT_VMMAP (vmmap data)");
21835 case NT_FREEBSD_PROCSTAT_GROUPS:
21836 return _("NT_PROCSTAT_GROUPS (groups data)");
21837 case NT_FREEBSD_PROCSTAT_UMASK:
21838 return _("NT_PROCSTAT_UMASK (umask data)");
21839 case NT_FREEBSD_PROCSTAT_RLIMIT:
21840 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
21841 case NT_FREEBSD_PROCSTAT_OSREL:
21842 return _("NT_PROCSTAT_OSREL (osreldate data)");
21843 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
21844 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
21845 case NT_FREEBSD_PROCSTAT_AUXV:
21846 return _("NT_PROCSTAT_AUXV (auxv data)");
21847 case NT_FREEBSD_PTLWPINFO:
21848 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
21849 case NT_FREEBSD_X86_SEGBASES:
21850 return _("NT_X86_SEGBASES (x86 segment base registers)");
21852 return get_note_type (filedata, e_type);
21855 static const char *
21856 get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
21858 static char buff[64];
21860 switch (e_type)
21862 case NT_NETBSDCORE_PROCINFO:
21863 /* NetBSD core "procinfo" structure. */
21864 return _("NetBSD procinfo structure");
21866 case NT_NETBSDCORE_AUXV:
21867 return _("NetBSD ELF auxiliary vector data");
21869 case NT_NETBSDCORE_LWPSTATUS:
21870 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
21872 default:
21873 /* As of Jan 2020 there are no other machine-independent notes
21874 defined for NetBSD core files. If the note type is less
21875 than the start of the machine-dependent note types, we don't
21876 understand it. */
21878 if (e_type < NT_NETBSDCORE_FIRSTMACH)
21880 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21881 return buff;
21883 break;
21886 switch (filedata->file_header.e_machine)
21888 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
21889 and PT_GETFPREGS == mach+2. */
21891 case EM_OLD_ALPHA:
21892 case EM_ALPHA:
21893 case EM_SPARC:
21894 case EM_SPARC32PLUS:
21895 case EM_SPARCV9:
21896 switch (e_type)
21898 case NT_NETBSDCORE_FIRSTMACH + 0:
21899 return _("PT_GETREGS (reg structure)");
21900 case NT_NETBSDCORE_FIRSTMACH + 2:
21901 return _("PT_GETFPREGS (fpreg structure)");
21902 default:
21903 break;
21905 break;
21907 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
21908 There's also old PT___GETREGS40 == mach + 1 for old reg
21909 structure which lacks GBR. */
21910 case EM_SH:
21911 switch (e_type)
21913 case NT_NETBSDCORE_FIRSTMACH + 1:
21914 return _("PT___GETREGS40 (old reg structure)");
21915 case NT_NETBSDCORE_FIRSTMACH + 3:
21916 return _("PT_GETREGS (reg structure)");
21917 case NT_NETBSDCORE_FIRSTMACH + 5:
21918 return _("PT_GETFPREGS (fpreg structure)");
21919 default:
21920 break;
21922 break;
21924 /* On all other arch's, PT_GETREGS == mach+1 and
21925 PT_GETFPREGS == mach+3. */
21926 default:
21927 switch (e_type)
21929 case NT_NETBSDCORE_FIRSTMACH + 1:
21930 return _("PT_GETREGS (reg structure)");
21931 case NT_NETBSDCORE_FIRSTMACH + 3:
21932 return _("PT_GETFPREGS (fpreg structure)");
21933 default:
21934 break;
21938 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
21939 e_type - NT_NETBSDCORE_FIRSTMACH);
21940 return buff;
21943 static const char *
21944 get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
21946 switch (e_type)
21948 case NT_OPENBSD_PROCINFO:
21949 return _("OpenBSD procinfo structure");
21950 case NT_OPENBSD_AUXV:
21951 return _("OpenBSD ELF auxiliary vector data");
21952 case NT_OPENBSD_REGS:
21953 return _("OpenBSD regular registers");
21954 case NT_OPENBSD_FPREGS:
21955 return _("OpenBSD floating point registers");
21956 case NT_OPENBSD_WCOOKIE:
21957 return _("OpenBSD window cookie");
21960 return get_note_type (filedata, e_type);
21963 static const char *
21964 get_qnx_elfcore_note_type (Filedata * filedata, unsigned e_type)
21966 switch (e_type)
21968 case QNT_DEBUG_FULLPATH:
21969 return _("QNX debug fullpath");
21970 case QNT_DEBUG_RELOC:
21971 return _("QNX debug relocation");
21972 case QNT_STACK:
21973 return _("QNX stack");
21974 case QNT_GENERATOR:
21975 return _("QNX generator");
21976 case QNT_DEFAULT_LIB:
21977 return _("QNX default library");
21978 case QNT_CORE_SYSINFO:
21979 return _("QNX core sysinfo");
21980 case QNT_CORE_INFO:
21981 return _("QNX core info");
21982 case QNT_CORE_STATUS:
21983 return _("QNX core status");
21984 case QNT_CORE_GREG:
21985 return _("QNX general registers");
21986 case QNT_CORE_FPREG:
21987 return _("QNX floating point registers");
21988 case QNT_LINK_MAP:
21989 return _("QNX link map");
21992 return get_note_type (filedata, e_type);
21995 static const char *
21996 get_stapsdt_note_type (unsigned e_type)
21998 static char buff[64];
22000 switch (e_type)
22002 case NT_STAPSDT:
22003 return _("NT_STAPSDT (SystemTap probe descriptors)");
22005 default:
22006 break;
22009 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
22010 return buff;
22013 static bool
22014 print_stapsdt_note (Elf_Internal_Note *pnote)
22016 size_t len, maxlen;
22017 size_t addr_size = is_32bit_elf ? 4 : 8;
22018 char *data = pnote->descdata;
22019 char *data_end = pnote->descdata + pnote->descsz;
22020 uint64_t pc, base_addr, semaphore;
22021 char *provider, *probe, *arg_fmt;
22023 if (pnote->descsz < (addr_size * 3))
22024 goto stapdt_note_too_small;
22026 pc = byte_get ((unsigned char *) data, addr_size);
22027 data += addr_size;
22029 base_addr = byte_get ((unsigned char *) data, addr_size);
22030 data += addr_size;
22032 semaphore = byte_get ((unsigned char *) data, addr_size);
22033 data += addr_size;
22035 if (data >= data_end)
22036 goto stapdt_note_too_small;
22037 maxlen = data_end - data;
22038 len = strnlen (data, maxlen);
22039 if (len < maxlen)
22041 provider = data;
22042 data += len + 1;
22044 else
22045 goto stapdt_note_too_small;
22047 if (data >= data_end)
22048 goto stapdt_note_too_small;
22049 maxlen = data_end - data;
22050 len = strnlen (data, maxlen);
22051 if (len < maxlen)
22053 probe = data;
22054 data += len + 1;
22056 else
22057 goto stapdt_note_too_small;
22059 if (data >= data_end)
22060 goto stapdt_note_too_small;
22061 maxlen = data_end - data;
22062 len = strnlen (data, maxlen);
22063 if (len < maxlen)
22065 arg_fmt = data;
22066 data += len + 1;
22068 else
22069 goto stapdt_note_too_small;
22071 printf (_(" Provider: %s\n"), provider);
22072 printf (_(" Name: %s\n"), probe);
22073 printf (_(" Location: "));
22074 print_vma (pc, FULL_HEX);
22075 printf (_(", Base: "));
22076 print_vma (base_addr, FULL_HEX);
22077 printf (_(", Semaphore: "));
22078 print_vma (semaphore, FULL_HEX);
22079 printf ("\n");
22080 printf (_(" Arguments: %s\n"), arg_fmt);
22082 return data == data_end;
22084 stapdt_note_too_small:
22085 printf (_(" <corrupt - note is too small>\n"));
22086 error (_("corrupt stapdt note - the data size is too small\n"));
22087 return false;
22090 static bool
22091 print_fdo_note (Elf_Internal_Note * pnote)
22093 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
22095 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
22096 return true;
22098 if (pnote->descsz > 0 && pnote->type == FDO_DLOPEN_METADATA)
22100 printf (_(" Dlopen Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
22101 return true;
22103 return false;
22106 static const char *
22107 get_ia64_vms_note_type (unsigned e_type)
22109 static char buff[64];
22111 switch (e_type)
22113 case NT_VMS_MHD:
22114 return _("NT_VMS_MHD (module header)");
22115 case NT_VMS_LNM:
22116 return _("NT_VMS_LNM (language name)");
22117 case NT_VMS_SRC:
22118 return _("NT_VMS_SRC (source files)");
22119 case NT_VMS_TITLE:
22120 return "NT_VMS_TITLE";
22121 case NT_VMS_EIDC:
22122 return _("NT_VMS_EIDC (consistency check)");
22123 case NT_VMS_FPMODE:
22124 return _("NT_VMS_FPMODE (FP mode)");
22125 case NT_VMS_LINKTIME:
22126 return "NT_VMS_LINKTIME";
22127 case NT_VMS_IMGNAM:
22128 return _("NT_VMS_IMGNAM (image name)");
22129 case NT_VMS_IMGID:
22130 return _("NT_VMS_IMGID (image id)");
22131 case NT_VMS_LINKID:
22132 return _("NT_VMS_LINKID (link id)");
22133 case NT_VMS_IMGBID:
22134 return _("NT_VMS_IMGBID (build id)");
22135 case NT_VMS_GSTNAM:
22136 return _("NT_VMS_GSTNAM (sym table name)");
22137 case NT_VMS_ORIG_DYN:
22138 return "NT_VMS_ORIG_DYN";
22139 case NT_VMS_PATCHTIME:
22140 return "NT_VMS_PATCHTIME";
22141 default:
22142 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
22143 return buff;
22147 static bool
22148 print_ia64_vms_note (Elf_Internal_Note * pnote)
22150 unsigned int maxlen = pnote->descsz;
22152 if (maxlen < 2 || maxlen != pnote->descsz)
22153 goto desc_size_fail;
22155 switch (pnote->type)
22157 case NT_VMS_MHD:
22158 if (maxlen <= 36)
22159 goto desc_size_fail;
22161 size_t l = strnlen (pnote->descdata + 34, maxlen - 34);
22163 printf (_(" Creation date : %.17s\n"), pnote->descdata);
22164 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
22165 if (l + 34 < maxlen)
22167 printf (_(" Module name : %s\n"), pnote->descdata + 34);
22168 if (l + 35 < maxlen)
22169 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
22170 else
22171 printf (_(" Module version : <missing>\n"));
22173 else
22175 printf (_(" Module name : <missing>\n"));
22176 printf (_(" Module version : <missing>\n"));
22178 break;
22180 case NT_VMS_LNM:
22181 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
22182 break;
22184 case NT_VMS_FPMODE:
22185 printf (_(" Floating Point mode: "));
22186 if (maxlen < 8)
22187 goto desc_size_fail;
22188 /* FIXME: Generate an error if descsz > 8 ? */
22190 printf ("0x%016" PRIx64 "\n",
22191 byte_get ((unsigned char *) pnote->descdata, 8));
22192 break;
22194 case NT_VMS_LINKTIME:
22195 printf (_(" Link time: "));
22196 if (maxlen < 8)
22197 goto desc_size_fail;
22198 /* FIXME: Generate an error if descsz > 8 ? */
22200 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
22201 printf ("\n");
22202 break;
22204 case NT_VMS_PATCHTIME:
22205 printf (_(" Patch time: "));
22206 if (maxlen < 8)
22207 goto desc_size_fail;
22208 /* FIXME: Generate an error if descsz > 8 ? */
22210 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
22211 printf ("\n");
22212 break;
22214 case NT_VMS_ORIG_DYN:
22215 if (maxlen < 34)
22216 goto desc_size_fail;
22218 printf (_(" Major id: %u, minor id: %u\n"),
22219 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
22220 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
22221 printf (_(" Last modified : "));
22222 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
22223 printf (_("\n Link flags : "));
22224 printf ("0x%016" PRIx64 "\n",
22225 byte_get ((unsigned char *) pnote->descdata + 16, 8));
22226 printf (_(" Header flags: 0x%08x\n"),
22227 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
22228 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
22229 break;
22231 case NT_VMS_IMGNAM:
22232 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
22233 break;
22235 case NT_VMS_GSTNAM:
22236 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
22237 break;
22239 case NT_VMS_IMGID:
22240 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
22241 break;
22243 case NT_VMS_LINKID:
22244 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
22245 break;
22247 default:
22248 return false;
22251 return true;
22253 desc_size_fail:
22254 printf (_(" <corrupt - data size is too small>\n"));
22255 error (_("corrupt IA64 note: data size is too small\n"));
22256 return false;
22259 struct build_attr_cache {
22260 Filedata *filedata;
22261 char *strtab;
22262 uint64_t strtablen;
22263 Elf_Internal_Sym *symtab;
22264 uint64_t nsyms;
22265 } ba_cache;
22267 /* Find the symbol associated with a build attribute that is attached
22268 to address OFFSET. If PNAME is non-NULL then store the name of
22269 the symbol (if found) in the provided pointer, Returns NULL if a
22270 symbol could not be found. */
22272 static Elf_Internal_Sym *
22273 get_symbol_for_build_attribute (Filedata *filedata,
22274 uint64_t offset,
22275 bool is_open_attr,
22276 const char **pname)
22278 Elf_Internal_Sym *saved_sym = NULL;
22279 Elf_Internal_Sym *sym;
22281 if (filedata->section_headers != NULL
22282 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
22284 Elf_Internal_Shdr * symsec;
22286 free (ba_cache.strtab);
22287 ba_cache.strtab = NULL;
22288 free (ba_cache.symtab);
22289 ba_cache.symtab = NULL;
22291 /* Load the symbol and string sections. */
22292 for (symsec = filedata->section_headers;
22293 symsec < filedata->section_headers + filedata->file_header.e_shnum;
22294 symsec ++)
22296 if (symsec->sh_type == SHT_SYMTAB
22297 && get_symtab (filedata, symsec,
22298 &ba_cache.symtab, &ba_cache.nsyms,
22299 &ba_cache.strtab, &ba_cache.strtablen))
22300 break;
22302 ba_cache.filedata = filedata;
22305 if (ba_cache.symtab == NULL)
22306 return NULL;
22308 /* Find a symbol whose value matches offset. */
22309 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
22310 if (sym->st_value == offset)
22312 if (sym->st_name >= ba_cache.strtablen)
22313 /* Huh ? This should not happen. */
22314 continue;
22316 if (ba_cache.strtab[sym->st_name] == 0)
22317 continue;
22319 /* The AArch64, ARM and RISC-V architectures define mapping symbols
22320 (eg $d, $x, $t) which we want to ignore. */
22321 if (ba_cache.strtab[sym->st_name] == '$'
22322 && ba_cache.strtab[sym->st_name + 1] != 0
22323 && ba_cache.strtab[sym->st_name + 2] == 0)
22324 continue;
22326 if (is_open_attr)
22328 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
22329 and FILE or OBJECT symbols over NOTYPE symbols. We skip
22330 FUNC symbols entirely. */
22331 switch (ELF_ST_TYPE (sym->st_info))
22333 case STT_OBJECT:
22334 case STT_FILE:
22335 saved_sym = sym;
22336 if (sym->st_size)
22338 /* If the symbol has a size associated
22339 with it then we can stop searching. */
22340 sym = ba_cache.symtab + ba_cache.nsyms;
22342 continue;
22344 case STT_FUNC:
22345 /* Ignore function symbols. */
22346 continue;
22348 default:
22349 break;
22352 switch (ELF_ST_BIND (sym->st_info))
22354 case STB_GLOBAL:
22355 if (saved_sym == NULL
22356 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
22357 saved_sym = sym;
22358 break;
22360 case STB_LOCAL:
22361 if (saved_sym == NULL)
22362 saved_sym = sym;
22363 break;
22365 default:
22366 break;
22369 else
22371 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
22372 continue;
22374 saved_sym = sym;
22375 break;
22379 if (saved_sym && pname)
22380 * pname = ba_cache.strtab + saved_sym->st_name;
22382 return saved_sym;
22385 /* Returns true iff addr1 and addr2 are in the same section. */
22387 static bool
22388 same_section (Filedata * filedata, uint64_t addr1, uint64_t addr2)
22390 Elf_Internal_Shdr * a1;
22391 Elf_Internal_Shdr * a2;
22393 a1 = find_section_by_address (filedata, addr1);
22394 a2 = find_section_by_address (filedata, addr2);
22396 return a1 == a2 && a1 != NULL;
22399 static bool
22400 print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
22401 Filedata * filedata)
22403 static uint64_t global_offset = 0;
22404 static uint64_t global_end = 0;
22405 static uint64_t func_offset = 0;
22406 static uint64_t func_end = 0;
22408 Elf_Internal_Sym *sym;
22409 const char *name;
22410 uint64_t start;
22411 uint64_t end;
22412 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
22414 switch (pnote->descsz)
22416 case 0:
22417 /* A zero-length description means that the range of
22418 the previous note of the same type should be used. */
22419 if (is_open_attr)
22421 if (global_end > global_offset)
22422 printf (_(" Applies to region from %#" PRIx64
22423 " to %#" PRIx64 "\n"), global_offset, global_end);
22424 else
22425 printf (_(" Applies to region from %#" PRIx64
22426 "\n"), global_offset);
22428 else
22430 if (func_end > func_offset)
22431 printf (_(" Applies to region from %#" PRIx64
22432 " to %#" PRIx64 "\n"), func_offset, func_end);
22433 else
22434 printf (_(" Applies to region from %#" PRIx64
22435 "\n"), func_offset);
22437 return true;
22439 case 4:
22440 start = byte_get ((unsigned char *) pnote->descdata, 4);
22441 end = 0;
22442 break;
22444 case 8:
22445 start = byte_get ((unsigned char *) pnote->descdata, 4);
22446 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
22447 break;
22449 case 16:
22450 start = byte_get ((unsigned char *) pnote->descdata, 8);
22451 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
22452 break;
22454 default:
22455 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
22456 printf (_(" <invalid descsz>"));
22457 return false;
22460 name = NULL;
22461 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
22462 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
22463 in order to avoid them being confused with the start address of the
22464 first function in the file... */
22465 if (sym == NULL && is_open_attr)
22466 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
22467 & name);
22469 if (end == 0 && sym != NULL && sym->st_size > 0)
22470 end = start + sym->st_size;
22472 if (is_open_attr)
22474 /* FIXME: Need to properly allow for section alignment.
22475 16 is just the alignment used on x86_64. */
22476 if (global_end > 0
22477 && start > BFD_ALIGN (global_end, 16)
22478 /* Build notes are not guaranteed to be organised in order of
22479 increasing address, but we should find the all of the notes
22480 for one section in the same place. */
22481 && same_section (filedata, start, global_end))
22482 warn (_("Gap in build notes detected from %#" PRIx64
22483 " to %#" PRIx64 "\n"),
22484 global_end + 1, start - 1);
22486 printf (_(" Applies to region from %#" PRIx64), start);
22487 global_offset = start;
22489 if (end)
22491 printf (_(" to %#" PRIx64), end);
22492 global_end = end;
22495 else
22497 printf (_(" Applies to region from %#" PRIx64), start);
22498 func_offset = start;
22500 if (end)
22502 printf (_(" to %#" PRIx64), end);
22503 func_end = end;
22507 if (sym && name)
22508 printf (_(" (%s)"), name);
22510 printf ("\n");
22511 return true;
22514 static bool
22515 print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
22517 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
22518 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
22519 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
22520 char name_type;
22521 char name_attribute;
22522 const char * expected_types;
22523 const char * name = pnote->namedata;
22524 const char * text;
22525 signed int left;
22527 if (name == NULL || pnote->namesz < 2)
22529 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
22530 print_symbol_name (-20, _(" <corrupt name>"));
22531 return false;
22534 if (do_wide)
22535 left = 28;
22536 else
22537 left = 20;
22539 /* Version 2 of the spec adds a "GA" prefix to the name field. */
22540 if (name[0] == 'G' && name[1] == 'A')
22542 if (pnote->namesz < 4)
22544 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
22545 print_symbol_name (-20, _(" <corrupt name>"));
22546 return false;
22549 printf ("GA");
22550 name += 2;
22551 left -= 2;
22554 switch ((name_type = * name))
22556 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
22557 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
22558 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
22559 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
22560 printf ("%c", * name);
22561 left --;
22562 break;
22563 default:
22564 error (_("unrecognised attribute type in name field: %d\n"), name_type);
22565 print_symbol_name (-20, _("<unknown name type>"));
22566 return false;
22569 ++ name;
22570 text = NULL;
22572 switch ((name_attribute = * name))
22574 case GNU_BUILD_ATTRIBUTE_VERSION:
22575 text = _("<version>");
22576 expected_types = string_expected;
22577 ++ name;
22578 break;
22579 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
22580 text = _("<stack prot>");
22581 expected_types = "!+*";
22582 ++ name;
22583 break;
22584 case GNU_BUILD_ATTRIBUTE_RELRO:
22585 text = _("<relro>");
22586 expected_types = bool_expected;
22587 ++ name;
22588 break;
22589 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
22590 text = _("<stack size>");
22591 expected_types = number_expected;
22592 ++ name;
22593 break;
22594 case GNU_BUILD_ATTRIBUTE_TOOL:
22595 text = _("<tool>");
22596 expected_types = string_expected;
22597 ++ name;
22598 break;
22599 case GNU_BUILD_ATTRIBUTE_ABI:
22600 text = _("<ABI>");
22601 expected_types = "$*";
22602 ++ name;
22603 break;
22604 case GNU_BUILD_ATTRIBUTE_PIC:
22605 text = _("<PIC>");
22606 expected_types = number_expected;
22607 ++ name;
22608 break;
22609 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
22610 text = _("<short enum>");
22611 expected_types = bool_expected;
22612 ++ name;
22613 break;
22614 default:
22615 if (ISPRINT (* name))
22617 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
22619 if (len > left && ! do_wide)
22620 len = left;
22621 printf ("%.*s:", len, name);
22622 left -= len;
22623 name += len;
22625 else
22627 static char tmpbuf [128];
22629 error (_("unrecognised byte in name field: %d\n"), * name);
22630 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
22631 text = tmpbuf;
22632 name ++;
22634 expected_types = "*$!+";
22635 break;
22638 if (text)
22639 left -= printf ("%s", text);
22641 if (strchr (expected_types, name_type) == NULL)
22642 warn (_("attribute does not have an expected type (%c)\n"), name_type);
22644 if ((size_t) (name - pnote->namedata) > pnote->namesz)
22646 error (_("corrupt name field: namesz: %lu but parsing gets to %td\n"),
22647 pnote->namesz,
22648 name - pnote->namedata);
22649 return false;
22652 if (left < 1 && ! do_wide)
22653 return true;
22655 switch (name_type)
22657 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
22659 unsigned int bytes;
22660 uint64_t val = 0;
22661 unsigned int shift = 0;
22662 char *decoded = NULL;
22664 bytes = pnote->namesz - (name - pnote->namedata);
22665 if (bytes > 0)
22666 /* The -1 is because the name field is always 0 terminated, and we
22667 want to be able to ensure that the shift in the while loop below
22668 will not overflow. */
22669 -- bytes;
22671 if (bytes > sizeof (val))
22673 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
22674 bytes);
22675 bytes = sizeof (val);
22677 /* We do not bother to warn if bytes == 0 as this can
22678 happen with some early versions of the gcc plugin. */
22680 while (bytes --)
22682 uint64_t byte = *name++ & 0xff;
22684 val |= byte << shift;
22685 shift += 8;
22688 switch (name_attribute)
22690 case GNU_BUILD_ATTRIBUTE_PIC:
22691 switch (val)
22693 case 0: decoded = "static"; break;
22694 case 1: decoded = "pic"; break;
22695 case 2: decoded = "PIC"; break;
22696 case 3: decoded = "pie"; break;
22697 case 4: decoded = "PIE"; break;
22698 default: break;
22700 break;
22701 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
22702 switch (val)
22704 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
22705 case 0: decoded = "off"; break;
22706 case 1: decoded = "on"; break;
22707 case 2: decoded = "all"; break;
22708 case 3: decoded = "strong"; break;
22709 case 4: decoded = "explicit"; break;
22710 default: break;
22712 break;
22713 default:
22714 break;
22717 if (decoded != NULL)
22719 print_symbol_name (-left, decoded);
22720 left = 0;
22722 else if (val == 0)
22724 printf ("0x0");
22725 left -= 3;
22727 else
22729 if (do_wide)
22730 left -= printf ("0x%" PRIx64, val);
22731 else
22732 left -= printf ("0x%-.*" PRIx64, left, val);
22735 break;
22736 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
22737 left -= print_symbol_name (- left, name);
22738 break;
22739 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
22740 left -= print_symbol_name (- left, "true");
22741 break;
22742 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
22743 left -= print_symbol_name (- left, "false");
22744 break;
22747 if (do_wide && left > 0)
22748 printf ("%-*s", left, " ");
22750 return true;
22753 /* Print the contents of PNOTE as hex. */
22755 static void
22756 print_note_contents_hex (Elf_Internal_Note *pnote)
22758 if (pnote->descsz)
22760 size_t i;
22762 printf (_(" description data: "));
22763 for (i = 0; i < pnote->descsz; i++)
22764 printf ("%02x ", pnote->descdata[i] & 0xff);
22765 if (!do_wide)
22766 printf ("\n");
22769 if (do_wide)
22770 printf ("\n");
22773 #if defined HAVE_MSGPACK
22775 static void
22776 print_indents (int n)
22778 printf (" ");
22780 for (int i = 0; i < n; i++)
22781 printf (" ");
22784 /* Print OBJ in human-readable form. */
22786 static void
22787 dump_msgpack_obj (const msgpack_object *obj, int indent)
22789 switch (obj->type)
22791 case MSGPACK_OBJECT_NIL:
22792 printf ("(nil)");
22793 break;
22795 case MSGPACK_OBJECT_BOOLEAN:
22796 printf ("%s", obj->via.boolean ? "true" : "false");
22797 break;
22799 case MSGPACK_OBJECT_POSITIVE_INTEGER:
22800 printf ("%" PRIu64, obj->via.u64);
22801 break;
22803 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
22804 printf ("%" PRIi64, obj->via.i64);
22805 break;
22807 case MSGPACK_OBJECT_FLOAT32:
22808 case MSGPACK_OBJECT_FLOAT64:
22809 printf ("%f", obj->via.f64);
22810 break;
22812 case MSGPACK_OBJECT_STR:
22813 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
22814 break;
22816 case MSGPACK_OBJECT_ARRAY:
22818 const msgpack_object_array *array = &obj->via.array;
22820 printf ("[\n");
22821 ++indent;
22823 for (uint32_t i = 0; i < array->size; ++i)
22825 const msgpack_object *item = &array->ptr[i];
22827 print_indents (indent);
22828 dump_msgpack_obj (item, indent);
22829 printf (",\n");
22832 --indent;
22833 print_indents (indent);
22834 printf ("]");
22835 break;
22837 break;
22839 case MSGPACK_OBJECT_MAP:
22841 const msgpack_object_map *map = &obj->via.map;
22843 printf ("{\n");
22844 ++indent;
22846 for (uint32_t i = 0; i < map->size; ++i)
22848 const msgpack_object_kv *kv = &map->ptr[i];
22849 const msgpack_object *key = &kv->key;
22850 const msgpack_object *val = &kv->val;
22852 print_indents (indent);
22853 dump_msgpack_obj (key, indent);
22854 printf (": ");
22855 dump_msgpack_obj (val, indent);
22857 printf (",\n");
22860 --indent;
22861 print_indents (indent);
22862 printf ("}");
22864 break;
22867 case MSGPACK_OBJECT_BIN:
22868 printf ("(bin)");
22869 break;
22871 case MSGPACK_OBJECT_EXT:
22872 printf ("(ext)");
22873 break;
22877 static void
22878 dump_msgpack (const msgpack_unpacked *msg)
22880 print_indents (0);
22881 dump_msgpack_obj (&msg->data, 0);
22882 printf ("\n");
22885 #endif /* defined HAVE_MSGPACK */
22887 static bool
22888 print_amdgpu_note (Elf_Internal_Note *pnote)
22890 #if defined HAVE_MSGPACK
22891 /* If msgpack is available, decode and dump the note's content. */
22892 bool ret;
22893 msgpack_unpacked msg;
22894 msgpack_unpack_return msgpack_ret;
22896 assert (pnote->type == NT_AMDGPU_METADATA);
22898 msgpack_unpacked_init (&msg);
22899 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
22900 NULL);
22902 switch (msgpack_ret)
22904 case MSGPACK_UNPACK_SUCCESS:
22905 dump_msgpack (&msg);
22906 ret = true;
22907 break;
22909 default:
22910 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
22911 ret = false;
22912 break;
22915 msgpack_unpacked_destroy (&msg);
22916 return ret;
22917 #else
22918 /* msgpack is not available, dump contents as hex. */
22919 print_note_contents_hex (pnote);
22920 return true;
22921 #endif
22924 static bool
22925 print_qnx_note (Elf_Internal_Note *pnote)
22927 switch (pnote->type)
22929 case QNT_STACK:
22930 if (pnote->descsz != 12)
22931 goto desc_size_fail;
22933 printf (_(" Stack Size: 0x%" PRIx32 "\n"),
22934 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4));
22935 printf (_(" Stack allocated: %" PRIx32 "\n"),
22936 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
22937 printf (_(" Executable: %s\n"),
22938 ((unsigned) byte_get ((unsigned char *) pnote->descdata + 8, 1)) ? "no": "yes");
22939 break;
22941 default:
22942 print_note_contents_hex(pnote);
22944 return true;
22946 desc_size_fail:
22947 printf (_(" <corrupt - data size is too small>\n"));
22948 error (_("corrupt QNX note: data size is too small\n"));
22949 return false;
22953 /* Note that by the ELF standard, the name field is already null byte
22954 terminated, and namesz includes the terminating null byte.
22955 I.E. the value of namesz for the name "FSF" is 4.
22957 If the value of namesz is zero, there is no name present. */
22959 static bool
22960 process_note (Elf_Internal_Note * pnote,
22961 Filedata * filedata)
22963 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
22964 const char * nt;
22966 if (pnote->namesz == 0)
22967 /* If there is no note name, then use the default set of
22968 note type strings. */
22969 nt = get_note_type (filedata, pnote->type);
22971 else if (startswith (pnote->namedata, "GNU"))
22972 /* GNU-specific object file notes. */
22973 nt = get_gnu_elf_note_type (pnote->type);
22975 else if (startswith (pnote->namedata, "AMDGPU"))
22976 /* AMDGPU-specific object file notes. */
22977 nt = get_amdgpu_elf_note_type (pnote->type);
22979 else if (startswith (pnote->namedata, "FreeBSD"))
22980 /* FreeBSD-specific core file notes. */
22981 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
22983 else if (startswith (pnote->namedata, "NetBSD-CORE"))
22984 /* NetBSD-specific core file notes. */
22985 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
22987 else if (startswith (pnote->namedata, "NetBSD"))
22988 /* NetBSD-specific core file notes. */
22989 return process_netbsd_elf_note (pnote);
22991 else if (startswith (pnote->namedata, "PaX"))
22992 /* NetBSD-specific core file notes. */
22993 return process_netbsd_elf_note (pnote);
22995 else if (startswith (pnote->namedata, "OpenBSD"))
22996 /* OpenBSD-specific core file notes. */
22997 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
22999 else if (startswith (pnote->namedata, "QNX"))
23000 /* QNX-specific core file notes. */
23001 nt = get_qnx_elfcore_note_type (filedata, pnote->type);
23003 else if (startswith (pnote->namedata, "SPU/"))
23005 /* SPU-specific core file notes. */
23006 nt = pnote->namedata + 4;
23007 name = "SPU";
23010 else if (startswith (pnote->namedata, "IPF/VMS"))
23011 /* VMS/ia64-specific file notes. */
23012 nt = get_ia64_vms_note_type (pnote->type);
23014 else if (startswith (pnote->namedata, "stapsdt"))
23015 nt = get_stapsdt_note_type (pnote->type);
23017 else
23018 /* Don't recognize this note name; just use the default set of
23019 note type strings. */
23020 nt = get_note_type (filedata, pnote->type);
23022 printf (" ");
23024 if (((startswith (pnote->namedata, "GA")
23025 && strchr ("*$!+", pnote->namedata[2]) != NULL)
23026 || strchr ("*$!+", pnote->namedata[0]) != NULL)
23027 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
23028 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
23029 print_gnu_build_attribute_name (pnote);
23030 else
23031 print_symbol_name (-20, name);
23033 if (do_wide)
23034 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
23035 else
23036 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
23038 if (startswith (pnote->namedata, "IPF/VMS"))
23039 return print_ia64_vms_note (pnote);
23040 else if (startswith (pnote->namedata, "GNU"))
23041 return print_gnu_note (filedata, pnote);
23042 else if (startswith (pnote->namedata, "stapsdt"))
23043 return print_stapsdt_note (pnote);
23044 else if (startswith (pnote->namedata, "CORE"))
23045 return print_core_note (pnote);
23046 else if (startswith (pnote->namedata, "FDO"))
23047 return print_fdo_note (pnote);
23048 else if (((startswith (pnote->namedata, "GA")
23049 && strchr ("*$!+", pnote->namedata[2]) != NULL)
23050 || strchr ("*$!+", pnote->namedata[0]) != NULL)
23051 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
23052 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
23053 return print_gnu_build_attribute_description (pnote, filedata);
23054 else if (startswith (pnote->namedata, "AMDGPU")
23055 && pnote->type == NT_AMDGPU_METADATA)
23056 return print_amdgpu_note (pnote);
23057 else if (startswith (pnote->namedata, "QNX"))
23058 return print_qnx_note (pnote);
23060 print_note_contents_hex (pnote);
23061 return true;
23064 static bool
23065 process_notes_at (Filedata * filedata,
23066 Elf_Internal_Shdr * section,
23067 uint64_t offset,
23068 uint64_t length,
23069 uint64_t align)
23071 Elf_External_Note *pnotes;
23072 Elf_External_Note *external;
23073 char *end;
23074 bool res = true;
23076 if (length <= 0)
23077 return false;
23079 if (section)
23081 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
23082 if (pnotes)
23084 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
23086 free (pnotes);
23087 return false;
23091 else
23092 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
23093 _("notes"));
23095 if (pnotes == NULL)
23096 return false;
23098 external = pnotes;
23100 if (filedata->is_separate)
23101 printf (_("In linked file '%s': "), filedata->file_name);
23102 else
23103 printf ("\n");
23104 if (section)
23105 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
23106 else
23107 printf (_("Displaying notes found at file offset 0x%08" PRIx64
23108 " with length 0x%08" PRIx64 ":\n"),
23109 offset, length);
23111 /* NB: Some note sections may have alignment value of 0 or 1. gABI
23112 specifies that notes should be aligned to 4 bytes in 32-bit
23113 objects and to 8 bytes in 64-bit objects. As a Linux extension,
23114 we also support 4 byte alignment in 64-bit objects. If section
23115 alignment is less than 4, we treate alignment as 4 bytes. */
23116 if (align < 4)
23117 align = 4;
23118 else if (align != 4 && align != 8)
23120 warn (_("Corrupt note: alignment %" PRId64 ", expecting 4 or 8\n"),
23121 align);
23122 free (pnotes);
23123 return false;
23126 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
23128 end = (char *) pnotes + length;
23129 while ((char *) external < end)
23131 Elf_Internal_Note inote;
23132 size_t min_notesz;
23133 char * next;
23134 char * temp = NULL;
23135 size_t data_remaining = end - (char *) external;
23137 if (!is_ia64_vms (filedata))
23139 /* PR binutils/15191
23140 Make sure that there is enough data to read. */
23141 min_notesz = offsetof (Elf_External_Note, name);
23142 if (data_remaining < min_notesz)
23144 warn (ngettext ("Corrupt note: only %zd byte remains, "
23145 "not enough for a full note\n",
23146 "Corrupt note: only %zd bytes remain, "
23147 "not enough for a full note\n",
23148 data_remaining),
23149 data_remaining);
23150 break;
23152 data_remaining -= min_notesz;
23154 inote.type = BYTE_GET (external->type);
23155 inote.namesz = BYTE_GET (external->namesz);
23156 inote.namedata = external->name;
23157 inote.descsz = BYTE_GET (external->descsz);
23158 inote.descdata = ((char *) external
23159 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
23160 inote.descpos = offset + (inote.descdata - (char *) pnotes);
23161 next = ((char *) external
23162 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
23164 else
23166 Elf64_External_VMS_Note *vms_external;
23168 /* PR binutils/15191
23169 Make sure that there is enough data to read. */
23170 min_notesz = offsetof (Elf64_External_VMS_Note, name);
23171 if (data_remaining < min_notesz)
23173 warn (ngettext ("Corrupt note: only %zd byte remains, "
23174 "not enough for a full note\n",
23175 "Corrupt note: only %zd bytes remain, "
23176 "not enough for a full note\n",
23177 data_remaining),
23178 data_remaining);
23179 break;
23181 data_remaining -= min_notesz;
23183 vms_external = (Elf64_External_VMS_Note *) external;
23184 inote.type = BYTE_GET (vms_external->type);
23185 inote.namesz = BYTE_GET (vms_external->namesz);
23186 inote.namedata = vms_external->name;
23187 inote.descsz = BYTE_GET (vms_external->descsz);
23188 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
23189 inote.descpos = offset + (inote.descdata - (char *) pnotes);
23190 next = inote.descdata + align_power (inote.descsz, 3);
23193 /* PR 17531: file: 3443835e. */
23194 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
23195 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
23196 || (size_t) (inote.descdata - inote.namedata) > data_remaining
23197 || (size_t) (next - inote.descdata) < inote.descsz
23198 || ((size_t) (next - inote.descdata)
23199 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
23201 warn (_("note with invalid namesz and/or descsz found at offset %#tx\n"),
23202 (char *) external - (char *) pnotes);
23203 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx, alignment: %u\n"),
23204 inote.type, inote.namesz, inote.descsz, (int) align);
23205 break;
23208 external = (Elf_External_Note *) next;
23210 /* Verify that name is null terminated. It appears that at least
23211 one version of Linux (RedHat 6.0) generates corefiles that don't
23212 comply with the ELF spec by failing to include the null byte in
23213 namesz. */
23214 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
23216 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
23218 temp = (char *) malloc (inote.namesz + 1);
23219 if (temp == NULL)
23221 error (_("Out of memory allocating space for inote name\n"));
23222 res = false;
23223 break;
23226 memcpy (temp, inote.namedata, inote.namesz);
23227 inote.namedata = temp;
23229 inote.namedata[inote.namesz] = 0;
23232 if (! process_note (& inote, filedata))
23233 res = false;
23235 free (temp);
23236 temp = NULL;
23239 free (pnotes);
23241 return res;
23244 static bool
23245 process_corefile_note_segments (Filedata * filedata)
23247 Elf_Internal_Phdr *segment;
23248 unsigned int i;
23249 bool res = true;
23251 if (! get_program_headers (filedata))
23252 return true;
23254 for (i = 0, segment = filedata->program_headers;
23255 i < filedata->file_header.e_phnum;
23256 i++, segment++)
23258 if (segment->p_type == PT_NOTE)
23259 if (! process_notes_at (filedata, NULL, segment->p_offset,
23260 segment->p_filesz, segment->p_align))
23261 res = false;
23264 return res;
23267 static bool
23268 process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
23270 Elf_External_Note * pnotes;
23271 Elf_External_Note * external;
23272 char * end;
23273 bool res = true;
23275 if (length <= 0)
23276 return false;
23278 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
23279 _("v850 notes"));
23280 if (pnotes == NULL)
23281 return false;
23283 external = pnotes;
23284 end = (char*) pnotes + length;
23286 printf (_("\nDisplaying contents of Renesas V850 notes section at offset"
23287 " %#" PRIx64 " with length %#" PRIx64 ":\n"),
23288 offset, length);
23290 while ((char *) external + sizeof (Elf_External_Note) < end)
23292 Elf_External_Note * next;
23293 Elf_Internal_Note inote;
23295 inote.type = BYTE_GET (external->type);
23296 inote.namesz = BYTE_GET (external->namesz);
23297 inote.namedata = external->name;
23298 inote.descsz = BYTE_GET (external->descsz);
23299 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
23300 inote.descpos = offset + (inote.descdata - (char *) pnotes);
23302 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
23304 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
23305 inote.descdata = inote.namedata;
23306 inote.namesz = 0;
23309 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
23311 if ( ((char *) next > end)
23312 || ((char *) next < (char *) pnotes))
23314 warn (_("corrupt descsz found in note at offset %#tx\n"),
23315 (char *) external - (char *) pnotes);
23316 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
23317 inote.type, inote.namesz, inote.descsz);
23318 break;
23321 external = next;
23323 /* Prevent out-of-bounds indexing. */
23324 if ( inote.namedata + inote.namesz > end
23325 || inote.namedata + inote.namesz < inote.namedata)
23327 warn (_("corrupt namesz found in note at offset %#zx\n"),
23328 (char *) external - (char *) pnotes);
23329 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
23330 inote.type, inote.namesz, inote.descsz);
23331 break;
23334 printf (" %s: ", get_v850_elf_note_type (inote.type));
23336 if (! print_v850_note (& inote))
23338 res = false;
23339 printf ("<corrupt sizes: namesz: %#lx, descsz: %#lx>\n",
23340 inote.namesz, inote.descsz);
23344 free (pnotes);
23346 return res;
23349 static bool
23350 process_note_sections (Filedata * filedata)
23352 Elf_Internal_Shdr *section;
23353 size_t i;
23354 unsigned int n = 0;
23355 bool res = true;
23357 for (i = 0, section = filedata->section_headers;
23358 i < filedata->file_header.e_shnum && section != NULL;
23359 i++, section++)
23361 if (section->sh_type == SHT_NOTE)
23363 if (! process_notes_at (filedata, section, section->sh_offset,
23364 section->sh_size, section->sh_addralign))
23365 res = false;
23366 n++;
23369 if (( filedata->file_header.e_machine == EM_V800
23370 || filedata->file_header.e_machine == EM_V850
23371 || filedata->file_header.e_machine == EM_CYGNUS_V850)
23372 && section->sh_type == SHT_RENESAS_INFO)
23374 if (! process_v850_notes (filedata, section->sh_offset,
23375 section->sh_size))
23376 res = false;
23377 n++;
23381 if (n == 0)
23382 /* Try processing NOTE segments instead. */
23383 return process_corefile_note_segments (filedata);
23385 return res;
23388 static bool
23389 process_notes (Filedata * filedata)
23391 /* If we have not been asked to display the notes then do nothing. */
23392 if (! do_notes)
23393 return true;
23395 if (filedata->file_header.e_type != ET_CORE)
23396 return process_note_sections (filedata);
23398 /* No program headers means no NOTE segment. */
23399 if (filedata->file_header.e_phnum > 0)
23400 return process_corefile_note_segments (filedata);
23402 if (filedata->is_separate)
23403 printf (_("No notes found in linked file '%s'.\n"),
23404 filedata->file_name);
23405 else
23406 printf (_("No notes found file.\n"));
23408 return true;
23411 static unsigned char *
23412 display_public_gnu_attributes (unsigned char * start,
23413 const unsigned char * const end)
23415 printf (_(" Unknown GNU attribute: %s\n"), start);
23417 start += strnlen ((char *) start, end - start);
23418 display_raw_attribute (start, end);
23420 return (unsigned char *) end;
23423 static unsigned char *
23424 display_generic_attribute (unsigned char * start,
23425 unsigned int tag,
23426 const unsigned char * const end)
23428 if (tag == 0)
23429 return (unsigned char *) end;
23431 return display_tag_value (tag, start, end);
23434 static bool
23435 process_arch_specific (Filedata * filedata)
23437 if (! do_arch)
23438 return true;
23440 switch (filedata->file_header.e_machine)
23442 case EM_ARC:
23443 case EM_ARC_COMPACT:
23444 case EM_ARC_COMPACT2:
23445 case EM_ARC_COMPACT3:
23446 case EM_ARC_COMPACT3_64:
23447 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
23448 display_arc_attribute,
23449 display_generic_attribute);
23450 case EM_ARM:
23451 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
23452 display_arm_attribute,
23453 display_generic_attribute);
23455 case EM_MIPS:
23456 case EM_MIPS_RS3_LE:
23457 return process_mips_specific (filedata);
23459 case EM_MSP430:
23460 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
23461 display_msp430_attribute,
23462 display_msp430_gnu_attribute);
23464 case EM_RISCV:
23465 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
23466 display_riscv_attribute,
23467 display_generic_attribute);
23469 case EM_NDS32:
23470 return process_nds32_specific (filedata);
23472 case EM_68K:
23473 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
23474 display_m68k_gnu_attribute);
23476 case EM_PPC:
23477 case EM_PPC64:
23478 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
23479 display_power_gnu_attribute);
23481 case EM_S390:
23482 case EM_S390_OLD:
23483 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
23484 display_s390_gnu_attribute);
23486 case EM_SPARC:
23487 case EM_SPARC32PLUS:
23488 case EM_SPARCV9:
23489 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
23490 display_sparc_gnu_attribute);
23492 case EM_TI_C6000:
23493 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
23494 display_tic6x_attribute,
23495 display_generic_attribute);
23497 case EM_CSKY:
23498 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
23499 display_csky_attribute, NULL);
23501 default:
23502 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
23503 display_public_gnu_attributes,
23504 display_generic_attribute);
23508 static bool
23509 get_file_header (Filedata * filedata)
23511 /* Read in the identity array. */
23512 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
23513 return false;
23515 /* Determine how to read the rest of the header. */
23516 switch (filedata->file_header.e_ident[EI_DATA])
23518 default:
23519 case ELFDATANONE:
23520 case ELFDATA2LSB:
23521 byte_get = byte_get_little_endian;
23522 byte_put = byte_put_little_endian;
23523 break;
23524 case ELFDATA2MSB:
23525 byte_get = byte_get_big_endian;
23526 byte_put = byte_put_big_endian;
23527 break;
23530 /* For now we only support 32 bit and 64 bit ELF files. */
23531 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
23533 /* Read in the rest of the header. */
23534 if (is_32bit_elf)
23536 Elf32_External_Ehdr ehdr32;
23538 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
23539 return false;
23541 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
23542 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
23543 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
23544 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
23545 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
23546 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
23547 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
23548 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
23549 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
23550 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
23551 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
23552 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
23553 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
23555 else
23557 Elf64_External_Ehdr ehdr64;
23559 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
23560 return false;
23562 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
23563 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
23564 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
23565 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
23566 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
23567 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
23568 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
23569 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
23570 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
23571 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
23572 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
23573 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
23574 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
23577 return true;
23580 static void
23581 free_filedata (Filedata *filedata)
23583 free (filedata->program_interpreter);
23584 free (filedata->program_headers);
23585 free (filedata->section_headers);
23586 free (filedata->string_table);
23587 free (filedata->dump.dump_sects);
23588 free (filedata->dynamic_strings);
23589 free (filedata->dynamic_symbols);
23590 free (filedata->dynamic_syminfo);
23591 free (filedata->dynamic_section);
23593 while (filedata->symtab_shndx_list != NULL)
23595 elf_section_list *next = filedata->symtab_shndx_list->next;
23596 free (filedata->symtab_shndx_list);
23597 filedata->symtab_shndx_list = next;
23600 free (filedata->section_headers_groups);
23602 if (filedata->section_groups)
23604 size_t i;
23605 struct group_list * g;
23606 struct group_list * next;
23608 for (i = 0; i < filedata->group_count; i++)
23610 for (g = filedata->section_groups [i].root; g != NULL; g = next)
23612 next = g->next;
23613 free (g);
23617 free (filedata->section_groups);
23619 memset (&filedata->section_headers, 0,
23620 sizeof (Filedata) - offsetof (Filedata, section_headers));
23623 static void
23624 close_file (Filedata * filedata)
23626 if (filedata)
23628 if (filedata->handle)
23629 fclose (filedata->handle);
23630 free (filedata);
23634 void
23635 close_debug_file (void * data)
23637 free_filedata ((Filedata *) data);
23638 close_file ((Filedata *) data);
23641 static Filedata *
23642 open_file (const char * pathname, bool is_separate)
23644 struct stat statbuf;
23645 Filedata * filedata = NULL;
23647 if (stat (pathname, & statbuf) < 0
23648 || ! S_ISREG (statbuf.st_mode))
23649 goto fail;
23651 filedata = calloc (1, sizeof * filedata);
23652 if (filedata == NULL)
23653 goto fail;
23655 filedata->handle = fopen (pathname, "rb");
23656 if (filedata->handle == NULL)
23657 goto fail;
23659 filedata->file_size = statbuf.st_size;
23660 filedata->file_name = pathname;
23661 filedata->is_separate = is_separate;
23663 if (! get_file_header (filedata))
23664 goto fail;
23666 if (!get_section_headers (filedata, false))
23667 goto fail;
23669 return filedata;
23671 fail:
23672 if (filedata)
23674 if (filedata->handle)
23675 fclose (filedata->handle);
23676 free (filedata);
23678 return NULL;
23681 void *
23682 open_debug_file (const char * pathname)
23684 return open_file (pathname, true);
23687 static void
23688 initialise_dump_sects (Filedata * filedata)
23690 /* Initialise the dump_sects array from the cmdline_dump_sects array.
23691 Note we do this even if cmdline_dump_sects is empty because we
23692 must make sure that the dump_sets array is zeroed out before each
23693 object file is processed. */
23694 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
23695 memset (filedata->dump.dump_sects, 0,
23696 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
23698 if (cmdline.num_dump_sects > 0)
23700 if (filedata->dump.num_dump_sects == 0)
23701 /* A sneaky way of allocating the dump_sects array. */
23702 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
23704 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
23705 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
23706 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
23710 static bool
23711 might_need_separate_debug_info (Filedata * filedata)
23713 /* Debuginfo files do not need further separate file loading. */
23714 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
23715 return false;
23717 /* Since do_follow_links might be enabled by default, only treat it as an
23718 indication that separate files should be loaded if setting it was a
23719 deliberate user action. */
23720 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
23721 return true;
23723 if (process_links || do_syms || do_unwind
23724 || dump_any_debugging || do_dump || do_debugging)
23725 return true;
23727 return false;
23730 /* Process one ELF object file according to the command line options.
23731 This file may actually be stored in an archive. The file is
23732 positioned at the start of the ELF object. Returns TRUE if no
23733 problems were encountered, FALSE otherwise. */
23735 static bool
23736 process_object (Filedata * filedata)
23738 bool have_separate_files;
23739 unsigned int i;
23740 bool res;
23742 if (! get_file_header (filedata))
23744 error (_("%s: Failed to read file header\n"), filedata->file_name);
23745 return false;
23748 /* Initialise per file variables. */
23749 for (i = ARRAY_SIZE (filedata->version_info); i--;)
23750 filedata->version_info[i] = 0;
23752 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
23753 filedata->dynamic_info[i] = 0;
23754 filedata->dynamic_info_DT_GNU_HASH = 0;
23755 filedata->dynamic_info_DT_MIPS_XHASH = 0;
23757 /* Process the file. */
23758 if (show_name)
23759 printf (_("\nFile: %s\n"), filedata->file_name);
23761 initialise_dump_sects (filedata);
23763 /* There may be some extensions in the first section header. Don't
23764 bomb if we can't read it. */
23765 get_section_headers (filedata, true);
23767 if (! process_file_header (filedata))
23769 res = false;
23770 goto out;
23773 /* Throw away the single section header read above, so that we
23774 re-read the entire set. */
23775 free (filedata->section_headers);
23776 filedata->section_headers = NULL;
23778 if (! process_section_headers (filedata))
23780 /* Without loaded section headers we cannot process lots of things. */
23781 do_unwind = do_version = do_dump = do_arch = false;
23783 if (! do_using_dynamic)
23784 do_syms = do_dyn_syms = do_reloc = false;
23787 if (! process_section_groups (filedata))
23788 /* Without loaded section groups we cannot process unwind. */
23789 do_unwind = false;
23791 process_program_headers (filedata);
23793 res = process_dynamic_section (filedata);
23795 if (! process_relocs (filedata))
23796 res = false;
23798 if (! process_unwind (filedata))
23799 res = false;
23801 if (! process_symbol_table (filedata))
23802 res = false;
23804 if (! process_lto_symbol_tables (filedata))
23805 res = false;
23807 if (! process_syminfo (filedata))
23808 res = false;
23810 if (! process_version_sections (filedata))
23811 res = false;
23813 if (might_need_separate_debug_info (filedata))
23814 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
23815 else
23816 have_separate_files = false;
23818 if (! process_section_contents (filedata))
23819 res = false;
23821 if (have_separate_files)
23823 separate_info * d;
23825 for (d = first_separate_info; d != NULL; d = d->next)
23827 initialise_dump_sects (d->handle);
23829 if (process_links && ! process_file_header (d->handle))
23830 res = false;
23831 else if (! process_section_headers (d->handle))
23832 res = false;
23833 else if (! process_section_contents (d->handle))
23834 res = false;
23835 else if (process_links)
23837 if (! process_section_groups (d->handle))
23838 res = false;
23839 process_program_headers (d->handle);
23840 if (! process_dynamic_section (d->handle))
23841 res = false;
23842 if (! process_relocs (d->handle))
23843 res = false;
23844 if (! process_unwind (d->handle))
23845 res = false;
23846 if (! process_symbol_table (d->handle))
23847 res = false;
23848 if (! process_lto_symbol_tables (d->handle))
23849 res = false;
23850 if (! process_syminfo (d->handle))
23851 res = false;
23852 if (! process_version_sections (d->handle))
23853 res = false;
23854 if (! process_notes (d->handle))
23855 res = false;
23859 /* The file handles are closed by the call to free_debug_memory() below. */
23862 if (! process_notes (filedata))
23863 res = false;
23865 if (! process_gnu_liblist (filedata))
23866 res = false;
23868 if (! process_arch_specific (filedata))
23869 res = false;
23871 out:
23872 free_filedata (filedata);
23874 free_debug_memory ();
23876 return res;
23879 /* Process an ELF archive.
23880 On entry the file is positioned just after the ARMAG string.
23881 Returns TRUE upon success, FALSE otherwise. */
23883 static bool
23884 process_archive (Filedata * filedata, bool is_thin_archive)
23886 struct archive_info arch;
23887 struct archive_info nested_arch;
23888 size_t got;
23889 bool ret = true;
23891 show_name = true;
23893 /* The ARCH structure is used to hold information about this archive. */
23894 arch.file_name = NULL;
23895 arch.file = NULL;
23896 arch.index_array = NULL;
23897 arch.sym_table = NULL;
23898 arch.longnames = NULL;
23900 /* The NESTED_ARCH structure is used as a single-item cache of information
23901 about a nested archive (when members of a thin archive reside within
23902 another regular archive file). */
23903 nested_arch.file_name = NULL;
23904 nested_arch.file = NULL;
23905 nested_arch.index_array = NULL;
23906 nested_arch.sym_table = NULL;
23907 nested_arch.longnames = NULL;
23909 if (setup_archive (&arch, filedata->file_name, filedata->handle,
23910 filedata->file_size, is_thin_archive,
23911 do_archive_index) != 0)
23913 ret = false;
23914 goto out;
23917 if (do_archive_index)
23919 if (arch.sym_table == NULL)
23920 error (_("%s: unable to dump the index as none was found\n"),
23921 filedata->file_name);
23922 else
23924 uint64_t i, l;
23925 uint64_t current_pos;
23927 printf (_("Index of archive %s: (%" PRIu64 " entries,"
23928 " %#" PRIx64 " bytes in the symbol table)\n"),
23929 filedata->file_name, arch.index_num,
23930 arch.sym_size);
23932 current_pos = ftell (filedata->handle);
23934 for (i = l = 0; i < arch.index_num; i++)
23936 if (i == 0
23937 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
23939 char * member_name
23940 = get_archive_member_name_at (&arch, arch.index_array[i],
23941 &nested_arch);
23943 if (member_name != NULL)
23945 char * qualified_name
23946 = make_qualified_name (&arch, &nested_arch,
23947 member_name);
23949 if (qualified_name != NULL)
23951 printf (_("Contents of binary %s at offset "),
23952 qualified_name);
23953 (void) print_vma (arch.index_array[i], PREFIX_HEX);
23954 putchar ('\n');
23955 free (qualified_name);
23957 free (member_name);
23961 if (l >= arch.sym_size)
23963 error (_("%s: end of the symbol table reached "
23964 "before the end of the index\n"),
23965 filedata->file_name);
23966 ret = false;
23967 break;
23969 /* PR 17531: file: 0b6630b2. */
23970 printf ("\t%.*s\n",
23971 (int) (arch.sym_size - l), arch.sym_table + l);
23972 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
23975 if (arch.uses_64bit_indices)
23976 l = (l + 7) & ~ 7;
23977 else
23978 l += l & 1;
23980 if (l < arch.sym_size)
23982 error (ngettext ("%s: %" PRId64 " byte remains in the symbol table, "
23983 "but without corresponding entries in "
23984 "the index table\n",
23985 "%s: %" PRId64 " bytes remain in the symbol table, "
23986 "but without corresponding entries in "
23987 "the index table\n",
23988 arch.sym_size - l),
23989 filedata->file_name, arch.sym_size - l);
23990 ret = false;
23993 if (fseek64 (filedata->handle, current_pos, SEEK_SET) != 0)
23995 error (_("%s: failed to seek back to start of object files "
23996 "in the archive\n"),
23997 filedata->file_name);
23998 ret = false;
23999 goto out;
24003 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
24004 && !do_segments && !do_header && !do_dump && !do_version
24005 && !do_histogram && !do_debugging && !do_arch && !do_notes
24006 && !do_section_groups && !do_dyn_syms)
24008 ret = true; /* Archive index only. */
24009 goto out;
24013 while (1)
24015 char * name;
24016 size_t namelen;
24017 char * qualified_name;
24019 /* Read the next archive header. */
24020 if (fseek64 (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
24022 error (_("%s: failed to seek to next archive header\n"),
24023 arch.file_name);
24024 ret = false;
24025 break;
24027 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
24028 if (got != sizeof arch.arhdr)
24030 if (got == 0)
24031 break;
24032 /* PR 24049 - we cannot use filedata->file_name as this will
24033 have already been freed. */
24034 error (_("%s: failed to read archive header\n"), arch.file_name);
24036 ret = false;
24037 break;
24039 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
24041 error (_("%s: did not find a valid archive header\n"),
24042 arch.file_name);
24043 ret = false;
24044 break;
24047 arch.next_arhdr_offset += sizeof arch.arhdr;
24049 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
24051 name = get_archive_member_name (&arch, &nested_arch);
24052 if (name == NULL)
24054 error (_("%s: bad archive file name\n"), arch.file_name);
24055 ret = false;
24056 break;
24058 namelen = strlen (name);
24060 qualified_name = make_qualified_name (&arch, &nested_arch, name);
24061 if (qualified_name == NULL)
24063 error (_("%s: bad archive file name\n"), arch.file_name);
24064 free (name);
24065 ret = false;
24066 break;
24069 if (is_thin_archive && arch.nested_member_origin == 0)
24071 /* This is a proxy for an external member of a thin archive. */
24072 Filedata * member_filedata;
24073 char * member_file_name = adjust_relative_path
24074 (filedata->file_name, name, namelen);
24076 free (name);
24077 if (member_file_name == NULL)
24079 free (qualified_name);
24080 ret = false;
24081 break;
24084 member_filedata = open_file (member_file_name, false);
24085 if (member_filedata == NULL)
24087 error (_("Input file '%s' is not readable.\n"), member_file_name);
24088 free (member_file_name);
24089 free (qualified_name);
24090 ret = false;
24091 break;
24094 filedata->archive_file_offset = arch.nested_member_origin;
24095 member_filedata->file_name = qualified_name;
24097 /* The call to process_object() expects the file to be at the beginning. */
24098 rewind (member_filedata->handle);
24100 if (! process_object (member_filedata))
24101 ret = false;
24103 close_file (member_filedata);
24104 free (member_file_name);
24106 else if (is_thin_archive)
24108 Filedata thin_filedata;
24110 memset (&thin_filedata, 0, sizeof (thin_filedata));
24112 /* PR 15140: Allow for corrupt thin archives. */
24113 if (nested_arch.file == NULL)
24115 error (_("%s: contains corrupt thin archive: %s\n"),
24116 qualified_name, name);
24117 free (qualified_name);
24118 free (name);
24119 ret = false;
24120 break;
24122 free (name);
24124 /* This is a proxy for a member of a nested archive. */
24125 filedata->archive_file_offset
24126 = arch.nested_member_origin + sizeof arch.arhdr;
24128 /* The nested archive file will have been opened and setup by
24129 get_archive_member_name. */
24130 if (fseek64 (nested_arch.file, filedata->archive_file_offset,
24131 SEEK_SET) != 0)
24133 error (_("%s: failed to seek to archive member.\n"),
24134 nested_arch.file_name);
24135 free (qualified_name);
24136 ret = false;
24137 break;
24140 thin_filedata.handle = nested_arch.file;
24141 thin_filedata.file_name = qualified_name;
24143 if (! process_object (& thin_filedata))
24144 ret = false;
24146 else
24148 free (name);
24149 filedata->archive_file_offset = arch.next_arhdr_offset;
24150 filedata->file_name = qualified_name;
24151 if (! process_object (filedata))
24152 ret = false;
24153 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
24154 /* Stop looping with "negative" archive_file_size. */
24155 if (arch.next_arhdr_offset < filedata->archive_file_size)
24156 arch.next_arhdr_offset = -1ul;
24159 free (qualified_name);
24162 out:
24163 if (nested_arch.file != NULL)
24164 fclose (nested_arch.file);
24165 release_archive (&nested_arch);
24166 release_archive (&arch);
24168 return ret;
24171 static bool
24172 process_file (char * file_name)
24174 Filedata * filedata = NULL;
24175 struct stat statbuf;
24176 char armag[SARMAG];
24177 bool ret = true;
24179 if (stat (file_name, &statbuf) < 0)
24181 if (errno == ENOENT)
24182 error (_("'%s': No such file\n"), file_name);
24183 else
24184 error (_("Could not locate '%s'. System error message: %s\n"),
24185 file_name, strerror (errno));
24186 return false;
24189 if (! S_ISREG (statbuf.st_mode))
24191 error (_("'%s' is not an ordinary file\n"), file_name);
24192 return false;
24195 filedata = calloc (1, sizeof * filedata);
24196 if (filedata == NULL)
24198 error (_("Out of memory allocating file data structure\n"));
24199 return false;
24202 filedata->file_name = file_name;
24203 filedata->handle = fopen (file_name, "rb");
24204 if (filedata->handle == NULL)
24206 error (_("Input file '%s' is not readable.\n"), file_name);
24207 free (filedata);
24208 return false;
24211 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
24213 error (_("%s: Failed to read file's magic number\n"), file_name);
24214 fclose (filedata->handle);
24215 free (filedata);
24216 return false;
24219 filedata->file_size = statbuf.st_size;
24220 filedata->is_separate = false;
24222 if (memcmp (armag, ARMAG, SARMAG) == 0)
24224 if (! process_archive (filedata, false))
24225 ret = false;
24227 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
24229 if ( ! process_archive (filedata, true))
24230 ret = false;
24232 else
24234 if (do_archive_index && !check_all)
24235 error (_("File %s is not an archive so its index cannot be displayed.\n"),
24236 file_name);
24238 rewind (filedata->handle);
24239 filedata->archive_file_size = filedata->archive_file_offset = 0;
24241 if (! process_object (filedata))
24242 ret = false;
24245 close_debug_file (filedata);
24247 free (ba_cache.strtab);
24248 ba_cache.strtab = NULL;
24249 free (ba_cache.symtab);
24250 ba_cache.symtab = NULL;
24251 ba_cache.filedata = NULL;
24253 return ret;
24256 #ifdef SUPPORT_DISASSEMBLY
24257 /* Needed by the i386 disassembler. For extra credit, someone could
24258 fix this so that we insert symbolic addresses here, esp for GOT/PLT
24259 symbols. */
24261 void
24262 print_address (unsigned int addr, FILE * outfile)
24264 fprintf (outfile,"0x%8.8x", addr);
24267 /* Needed by the i386 disassembler. */
24269 void
24270 db_task_printsym (unsigned int addr)
24272 print_address (addr, stderr);
24274 #endif
24277 main (int argc, char ** argv)
24279 int err;
24281 #ifdef HAVE_LC_MESSAGES
24282 setlocale (LC_MESSAGES, "");
24283 #endif
24284 setlocale (LC_CTYPE, "");
24285 bindtextdomain (PACKAGE, LOCALEDIR);
24286 textdomain (PACKAGE);
24288 expandargv (&argc, &argv);
24290 parse_args (& cmdline, argc, argv);
24292 if (optind < (argc - 1))
24293 /* When displaying information for more than one file,
24294 prefix the information with the file name. */
24295 show_name = true;
24296 else if (optind >= argc)
24298 /* Ensure that the warning is always displayed. */
24299 do_checks = true;
24301 warn (_("Nothing to do.\n"));
24302 usage (stderr);
24305 err = false;
24306 while (optind < argc)
24307 if (! process_file (argv[optind++]))
24308 err = true;
24310 free (cmdline.dump_sects);
24312 free (dump_ctf_symtab_name);
24313 free (dump_ctf_strtab_name);
24314 free (dump_ctf_parent_name);
24316 return err ? EXIT_FAILURE : EXIT_SUCCESS;