arm, objdump: print obsolote warning when 26-bit set in instructions
[binutils-gdb.git] / binutils / readelf.c
blob73163e0ee21b0fb8c2cd82789ff349465c535dae
1 /* readelf.c -- display contents of an ELF format file
2 Copyright (C) 1998-2024 Free Software Foundation, Inc.
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
5 Modifications by Nick Clifton <nickc@redhat.com>
7 This file is part of GNU Binutils.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
24 /* The difference between readelf and objdump:
26 Both programs are capable of displaying the contents of ELF format files,
27 so why does the binutils project have two file dumpers ?
29 The reason is that objdump sees an ELF file through a BFD filter of the
30 world; if BFD has a bug where, say, it disagrees about a machine constant
31 in e_flags, then the odds are good that it will remain internally
32 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
33 GAS sees it the BFD way. There was need for a tool to go find out what
34 the file actually says.
36 This is why the readelf program does not link against the BFD library - it
37 exists as an independent program to help verify the correct working of BFD.
39 There is also the case that readelf can provide more information about an
40 ELF file than is provided by objdump. In particular it can display DWARF
41 debugging information which (at the moment) objdump cannot. */
43 #include "sysdep.h"
44 #include <assert.h>
45 #include <time.h>
46 #include <zlib.h>
47 #ifdef HAVE_ZSTD
48 #include <zstd.h>
49 #endif
50 #include <wchar.h>
52 #if defined HAVE_MSGPACK
53 #include <msgpack.h>
54 #endif
56 /* Define BFD64 here, even if our default architecture is 32 bit ELF
57 as this will allow us to read in and parse 64bit and 32bit ELF files. */
58 #define BFD64
60 #include "bfd.h"
61 #include "bucomm.h"
62 #include "elfcomm.h"
63 #include "demanguse.h"
64 #include "dwarf.h"
65 #include "ctf-api.h"
66 #include "sframe-api.h"
67 #include "demangle.h"
69 #include "elf/common.h"
70 #include "elf/external.h"
71 #include "elf/internal.h"
74 /* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
75 we can obtain the H8 reloc numbers. We need these for the
76 get_reloc_size() function. We include h8.h again after defining
77 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
79 #include "elf/h8.h"
80 #undef _ELF_H8_H
82 /* Undo the effects of #including reloc-macros.h. */
84 #undef START_RELOC_NUMBERS
85 #undef RELOC_NUMBER
86 #undef FAKE_RELOC
87 #undef EMPTY_RELOC
88 #undef END_RELOC_NUMBERS
89 #undef _RELOC_MACROS_H
91 /* The following headers use the elf/reloc-macros.h file to
92 automatically generate relocation recognition functions
93 such as elf_mips_reloc_type() */
95 #define RELOC_MACROS_GEN_FUNC
97 #include "elf/aarch64.h"
98 #include "elf/alpha.h"
99 #include "elf/amdgpu.h"
100 #include "elf/arc.h"
101 #include "elf/arm.h"
102 #include "elf/avr.h"
103 #include "elf/bfin.h"
104 #include "elf/cr16.h"
105 #include "elf/cris.h"
106 #include "elf/crx.h"
107 #include "elf/csky.h"
108 #include "elf/d10v.h"
109 #include "elf/d30v.h"
110 #include "elf/dlx.h"
111 #include "elf/bpf.h"
112 #include "elf/epiphany.h"
113 #include "elf/fr30.h"
114 #include "elf/frv.h"
115 #include "elf/ft32.h"
116 #include "elf/h8.h"
117 #include "elf/hppa.h"
118 #include "elf/i386.h"
119 #include "elf/i370.h"
120 #include "elf/i860.h"
121 #include "elf/i960.h"
122 #include "elf/ia64.h"
123 #include "elf/ip2k.h"
124 #include "elf/kvx.h"
125 #include "elf/lm32.h"
126 #include "elf/iq2000.h"
127 #include "elf/m32c.h"
128 #include "elf/m32r.h"
129 #include "elf/m68k.h"
130 #include "elf/m68hc11.h"
131 #include "elf/s12z.h"
132 #include "elf/mcore.h"
133 #include "elf/mep.h"
134 #include "elf/metag.h"
135 #include "elf/microblaze.h"
136 #include "elf/mips.h"
137 #include "elf/mmix.h"
138 #include "elf/mn10200.h"
139 #include "elf/mn10300.h"
140 #include "elf/moxie.h"
141 #include "elf/mt.h"
142 #include "elf/msp430.h"
143 #include "elf/nds32.h"
144 #include "elf/nfp.h"
145 #include "elf/nios2.h"
146 #include "elf/or1k.h"
147 #include "elf/pj.h"
148 #include "elf/ppc.h"
149 #include "elf/ppc64.h"
150 #include "elf/pru.h"
151 #include "elf/riscv.h"
152 #include "elf/rl78.h"
153 #include "elf/rx.h"
154 #include "elf/s390.h"
155 #include "elf/score.h"
156 #include "elf/sh.h"
157 #include "elf/sparc.h"
158 #include "elf/spu.h"
159 #include "elf/tic6x.h"
160 #include "elf/tilegx.h"
161 #include "elf/tilepro.h"
162 #include "elf/v850.h"
163 #include "elf/vax.h"
164 #include "elf/visium.h"
165 #include "elf/wasm32.h"
166 #include "elf/x86-64.h"
167 #include "elf/xgate.h"
168 #include "elf/xstormy16.h"
169 #include "elf/xtensa.h"
170 #include "elf/z80.h"
171 #include "elf/loongarch.h"
172 #include "elf/bpf.h"
174 #include "getopt.h"
175 #include "libiberty.h"
176 #include "safe-ctype.h"
177 #include "filenames.h"
179 #ifndef offsetof
180 #define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
181 #endif
183 typedef struct elf_section_list
185 Elf_Internal_Shdr * hdr;
186 struct elf_section_list * next;
187 } elf_section_list;
189 /* Flag bits indicating particular types of dump. */
190 #define HEX_DUMP (1 << 0) /* The -x command line switch. */
191 #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 the given section's name. Like print_symbol, except that it does not try
891 to print multibyte characters, it just interprets them as hex values. */
893 static const char *
894 printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
896 #define NUM_SEC_NAME_BUFS 5
897 #define MAX_PRINT_SEC_NAME_LEN 256
899 static int sec_name_buf_index = 0;
900 /* We use a rotating array of static buffers, so that multiple successive calls
901 to printable_section_name() will still work. eg when used in a printf. */
902 static char sec_name_buf [NUM_SEC_NAME_BUFS][MAX_PRINT_SEC_NAME_LEN + 1];
904 const char * name;
905 char * buf;
906 char * buf_start;
907 char c;
908 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
910 /* Validate the input parameters. */
911 if (filedata == NULL)
912 return _("<internal error>");
913 if (sec == NULL)
914 return _("<none>");
915 if (filedata->string_table == NULL)
916 return _("<no-strings>");
917 if (sec->sh_name >= filedata->string_table_length)
918 return _("<corrupt>");
920 /* Select a buffer to use. */
921 buf_start = buf = sec_name_buf[sec_name_buf_index];
922 if (++sec_name_buf_index >= NUM_SEC_NAME_BUFS)
923 sec_name_buf_index = 0;
925 name = section_name (filedata, sec);
927 while ((c = * name ++) != 0)
929 if (ISCNTRL (c))
931 if (remaining < 2)
932 break;
934 * buf ++ = '^';
935 * buf ++ = c + 0x40;
936 remaining -= 2;
938 else if (ISPRINT (c))
940 * buf ++ = c;
941 remaining -= 1;
943 else
945 static char hex[17] = "0123456789ABCDEF";
947 if (remaining < 4)
948 break;
949 * buf ++ = '<';
950 * buf ++ = hex[(c & 0xf0) >> 4];
951 * buf ++ = hex[c & 0x0f];
952 * buf ++ = '>';
953 remaining -= 4;
956 if (remaining == 0)
957 break;
960 * buf = 0;
961 return buf_start;
964 /* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
965 This OS has so many departures from the ELF standard that we test it at
966 many places. */
968 static inline bool
969 is_ia64_vms (Filedata * filedata)
971 return filedata->file_header.e_machine == EM_IA_64
972 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
975 static const char *
976 printable_section_name_from_index (Filedata * filedata,
977 size_t ndx,
978 bool * is_special)
980 if (is_special != NULL)
981 * is_special = true;
983 switch (ndx)
985 case SHN_UNDEF: return "UND";
986 case SHN_ABS: return "ABS";
987 case SHN_COMMON: return "COM";
988 break;
991 if (filedata != NULL)
993 switch (filedata->file_header.e_machine)
995 case EM_MIPS:
996 if (ndx == SHN_MIPS_SCOMMON)
997 return "SCOMMON";
998 if (ndx == SHN_MIPS_SUNDEFINED)
999 return "SUNDEF";
1000 break;
1002 case EM_TI_C6000:
1003 if (ndx == SHN_TIC6X_SCOMMON)
1004 return "SCOM";
1005 break;
1007 case EM_X86_64:
1008 case EM_L1OM:
1009 case EM_K1OM:
1010 if (ndx == SHN_X86_64_LCOMMON)
1011 return "LARGE_COM";
1012 break;
1014 case EM_IA_64:
1015 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1016 && ndx == SHN_IA_64_ANSI_COMMON)
1017 return "ANSI_COM";
1019 if (is_ia64_vms (filedata) && ndx == SHN_IA_64_VMS_SYMVEC)
1020 return "VMS_SYMVEC";
1021 break;
1023 default:
1024 break;
1027 if (filedata->section_headers != NULL
1028 && ndx < filedata->file_header.e_shnum)
1030 const char * res;
1032 res = printable_section_name (filedata, filedata->section_headers + ndx);
1033 if (is_special != NULL)
1034 * is_special = (res[0] == '<');
1036 return res;
1040 static char name_buf[40];
1041 unsigned int short_ndx = (unsigned int) (ndx & 0xffff);
1043 if (ndx >= SHN_LOPROC && ndx <= SHN_HIPROC)
1044 sprintf (name_buf, "PRC[0x%04x]", short_ndx);
1045 else if (ndx >= SHN_LOOS && ndx <= SHN_HIOS)
1046 sprintf (name_buf, "OS [0x%04x]", short_ndx);
1047 else if (ndx >= SHN_LORESERVE)
1048 sprintf (name_buf, "RSV[0x%04x]", short_ndx);
1049 else if (filedata->file_header.e_shnum != 0
1050 && ndx >= filedata->file_header.e_shnum)
1051 sprintf (name_buf, _("BAD[0x%lx]"), (long) ndx);
1052 else
1053 sprintf (name_buf, "<section 0x%lx>", (long) ndx);
1055 return name_buf;
1058 /* Return a pointer to section NAME, or NULL if no such section exists. */
1060 static Elf_Internal_Shdr *
1061 find_section (Filedata * filedata, const char * name)
1063 unsigned int i;
1065 if (filedata->section_headers == NULL)
1066 return NULL;
1068 for (i = 0; i < filedata->file_header.e_shnum; i++)
1069 if (section_name_valid (filedata, filedata->section_headers + i)
1070 && streq (section_name (filedata, filedata->section_headers + i),
1071 name))
1072 return filedata->section_headers + i;
1074 return NULL;
1077 /* Return a pointer to a section containing ADDR, or NULL if no such
1078 section exists. */
1080 static Elf_Internal_Shdr *
1081 find_section_by_address (Filedata * filedata, uint64_t addr)
1083 unsigned int i;
1085 if (filedata->section_headers == NULL)
1086 return NULL;
1088 for (i = 0; i < filedata->file_header.e_shnum; i++)
1090 Elf_Internal_Shdr *sec = filedata->section_headers + i;
1092 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
1093 return sec;
1096 return NULL;
1099 static Elf_Internal_Shdr *
1100 find_section_by_type (Filedata * filedata, unsigned int type)
1102 unsigned int i;
1104 if (filedata->section_headers == NULL)
1105 return NULL;
1107 for (i = 0; i < filedata->file_header.e_shnum; i++)
1109 Elf_Internal_Shdr *sec = filedata->section_headers + i;
1111 if (sec->sh_type == type)
1112 return sec;
1115 return NULL;
1118 static Elf_Internal_Shdr *
1119 find_section_by_name (Filedata * filedata, const char * name)
1121 unsigned int i;
1123 if (filedata->section_headers == NULL || filedata->string_table_length == 0)
1124 return NULL;
1126 for (i = 0; i < filedata->file_header.e_shnum; i++)
1128 Elf_Internal_Shdr *sec = filedata->section_headers + i;
1130 if (sec->sh_name < filedata->string_table_length
1131 && streq (name, filedata->string_table + sec->sh_name))
1132 return sec;
1135 return NULL;
1138 /* Return a pointer to section NAME, or NULL if no such section exists,
1139 restricted to the list of sections given in SET. */
1141 static Elf_Internal_Shdr *
1142 find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
1144 unsigned int i;
1146 if (filedata->section_headers == NULL)
1147 return NULL;
1149 if (set != NULL)
1151 while ((i = *set++) > 0)
1153 /* See PR 21156 for a reproducer. */
1154 if (i >= filedata->file_header.e_shnum)
1155 continue; /* FIXME: Should we issue an error message ? */
1157 if (section_name_valid (filedata, filedata->section_headers + i)
1158 && streq (section_name (filedata, filedata->section_headers + i),
1159 name))
1160 return filedata->section_headers + i;
1164 return find_section (filedata, name);
1167 /* Guess the relocation size commonly used by the specific machines. */
1169 static bool
1170 guess_is_rela (unsigned int e_machine)
1172 switch (e_machine)
1174 /* Targets that use REL relocations. */
1175 case EM_386:
1176 case EM_IAMCU:
1177 case EM_960:
1178 case EM_ARM:
1179 case EM_D10V:
1180 case EM_CYGNUS_D10V:
1181 case EM_DLX:
1182 case EM_MIPS:
1183 case EM_MIPS_RS3_LE:
1184 case EM_CYGNUS_M32R:
1185 case EM_SCORE:
1186 case EM_XGATE:
1187 case EM_NFP:
1188 case EM_BPF:
1189 return false;
1191 /* Targets that use RELA relocations. */
1192 case EM_68K:
1193 case EM_860:
1194 case EM_AARCH64:
1195 case EM_ADAPTEVA_EPIPHANY:
1196 case EM_ALPHA:
1197 case EM_ALTERA_NIOS2:
1198 case EM_ARC:
1199 case EM_ARC_COMPACT:
1200 case EM_ARC_COMPACT2:
1201 case EM_ARC_COMPACT3:
1202 case EM_ARC_COMPACT3_64:
1203 case EM_AVR:
1204 case EM_AVR_OLD:
1205 case EM_BLACKFIN:
1206 case EM_CR16:
1207 case EM_CRIS:
1208 case EM_CRX:
1209 case EM_CSKY:
1210 case EM_D30V:
1211 case EM_CYGNUS_D30V:
1212 case EM_FR30:
1213 case EM_FT32:
1214 case EM_CYGNUS_FR30:
1215 case EM_CYGNUS_FRV:
1216 case EM_H8S:
1217 case EM_H8_300:
1218 case EM_H8_300H:
1219 case EM_IA_64:
1220 case EM_IP2K:
1221 case EM_IP2K_OLD:
1222 case EM_IQ2000:
1223 case EM_KVX:
1224 case EM_LATTICEMICO32:
1225 case EM_M32C_OLD:
1226 case EM_M32C:
1227 case EM_M32R:
1228 case EM_MCORE:
1229 case EM_CYGNUS_MEP:
1230 case EM_METAG:
1231 case EM_MMIX:
1232 case EM_MN10200:
1233 case EM_CYGNUS_MN10200:
1234 case EM_MN10300:
1235 case EM_CYGNUS_MN10300:
1236 case EM_MOXIE:
1237 case EM_MSP430:
1238 case EM_MSP430_OLD:
1239 case EM_MT:
1240 case EM_NDS32:
1241 case EM_NIOS32:
1242 case EM_OR1K:
1243 case EM_PPC64:
1244 case EM_PPC:
1245 case EM_TI_PRU:
1246 case EM_RISCV:
1247 case EM_RL78:
1248 case EM_RX:
1249 case EM_S390:
1250 case EM_S390_OLD:
1251 case EM_SH:
1252 case EM_SPARC:
1253 case EM_SPARC32PLUS:
1254 case EM_SPARCV9:
1255 case EM_SPU:
1256 case EM_TI_C6000:
1257 case EM_TILEGX:
1258 case EM_TILEPRO:
1259 case EM_V800:
1260 case EM_V850:
1261 case EM_CYGNUS_V850:
1262 case EM_VAX:
1263 case EM_VISIUM:
1264 case EM_X86_64:
1265 case EM_L1OM:
1266 case EM_K1OM:
1267 case EM_XSTORMY16:
1268 case EM_XTENSA:
1269 case EM_XTENSA_OLD:
1270 case EM_MICROBLAZE:
1271 case EM_MICROBLAZE_OLD:
1272 case EM_WEBASSEMBLY:
1273 return true;
1275 case EM_68HC05:
1276 case EM_68HC08:
1277 case EM_68HC11:
1278 case EM_68HC16:
1279 case EM_FX66:
1280 case EM_ME16:
1281 case EM_MMA:
1282 case EM_NCPU:
1283 case EM_NDR1:
1284 case EM_PCP:
1285 case EM_ST100:
1286 case EM_ST19:
1287 case EM_ST7:
1288 case EM_ST9PLUS:
1289 case EM_STARCORE:
1290 case EM_SVX:
1291 case EM_TINYJ:
1292 default:
1293 warn (_("Don't know about relocations on this machine architecture\n"));
1294 return false;
1298 /* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
1299 Returns TRUE upon success, FALSE otherwise. If successful then a
1300 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
1301 and the number of relocs loaded is placed in *NRELASP. It is the caller's
1302 responsibility to free the allocated buffer. */
1304 static bool
1305 slurp_rela_relocs (Filedata *filedata,
1306 uint64_t rel_offset,
1307 uint64_t rel_size,
1308 Elf_Internal_Rela **relasp,
1309 uint64_t *nrelasp)
1311 Elf_Internal_Rela * relas;
1312 uint64_t nrelas;
1313 unsigned int i;
1315 if (is_32bit_elf)
1317 Elf32_External_Rela * erelas;
1319 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
1320 rel_size, _("32-bit relocation data"));
1321 if (!erelas)
1322 return false;
1324 nrelas = rel_size / sizeof (Elf32_External_Rela);
1326 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1327 sizeof (Elf_Internal_Rela));
1329 if (relas == NULL)
1331 free (erelas);
1332 error (_("out of memory parsing relocs\n"));
1333 return false;
1336 for (i = 0; i < nrelas; i++)
1338 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1339 relas[i].r_info = BYTE_GET (erelas[i].r_info);
1340 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
1343 free (erelas);
1345 else
1347 Elf64_External_Rela * erelas;
1349 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
1350 rel_size, _("64-bit relocation data"));
1351 if (!erelas)
1352 return false;
1354 nrelas = rel_size / sizeof (Elf64_External_Rela);
1356 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1357 sizeof (Elf_Internal_Rela));
1359 if (relas == NULL)
1361 free (erelas);
1362 error (_("out of memory parsing relocs\n"));
1363 return false;
1366 for (i = 0; i < nrelas; i++)
1368 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1369 relas[i].r_info = BYTE_GET (erelas[i].r_info);
1370 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
1372 if (filedata->file_header.e_machine == EM_MIPS
1373 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
1375 /* In little-endian objects, r_info isn't really a
1376 64-bit little-endian value: it has a 32-bit
1377 little-endian symbol index followed by four
1378 individual byte fields. Reorder INFO
1379 accordingly. */
1380 uint64_t inf = relas[i].r_info;
1381 inf = (((inf & 0xffffffff) << 32)
1382 | ((inf >> 56) & 0xff)
1383 | ((inf >> 40) & 0xff00)
1384 | ((inf >> 24) & 0xff0000)
1385 | ((inf >> 8) & 0xff000000));
1386 relas[i].r_info = inf;
1390 free (erelas);
1393 *relasp = relas;
1394 *nrelasp = nrelas;
1395 return true;
1398 /* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
1399 Returns TRUE upon success, FALSE otherwise. If successful then a
1400 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1401 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1402 responsibility to free the allocated buffer. */
1404 static bool
1405 slurp_rel_relocs (Filedata *filedata,
1406 uint64_t rel_offset,
1407 uint64_t rel_size,
1408 Elf_Internal_Rela **relsp,
1409 uint64_t *nrelsp)
1411 Elf_Internal_Rela * rels;
1412 uint64_t nrels;
1413 unsigned int i;
1415 if (is_32bit_elf)
1417 Elf32_External_Rel * erels;
1419 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
1420 rel_size, _("32-bit relocation data"));
1421 if (!erels)
1422 return false;
1424 nrels = rel_size / sizeof (Elf32_External_Rel);
1426 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
1428 if (rels == NULL)
1430 free (erels);
1431 error (_("out of memory parsing relocs\n"));
1432 return false;
1435 for (i = 0; i < nrels; i++)
1437 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1438 rels[i].r_info = BYTE_GET (erels[i].r_info);
1439 rels[i].r_addend = 0;
1442 free (erels);
1444 else
1446 Elf64_External_Rel * erels;
1448 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
1449 rel_size, _("64-bit relocation data"));
1450 if (!erels)
1451 return false;
1453 nrels = rel_size / sizeof (Elf64_External_Rel);
1455 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
1457 if (rels == NULL)
1459 free (erels);
1460 error (_("out of memory parsing relocs\n"));
1461 return false;
1464 for (i = 0; i < nrels; i++)
1466 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1467 rels[i].r_info = BYTE_GET (erels[i].r_info);
1468 rels[i].r_addend = 0;
1470 if (filedata->file_header.e_machine == EM_MIPS
1471 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
1473 /* In little-endian objects, r_info isn't really a
1474 64-bit little-endian value: it has a 32-bit
1475 little-endian symbol index followed by four
1476 individual byte fields. Reorder INFO
1477 accordingly. */
1478 uint64_t inf = rels[i].r_info;
1479 inf = (((inf & 0xffffffff) << 32)
1480 | ((inf >> 56) & 0xff)
1481 | ((inf >> 40) & 0xff00)
1482 | ((inf >> 24) & 0xff0000)
1483 | ((inf >> 8) & 0xff000000));
1484 rels[i].r_info = inf;
1488 free (erels);
1491 *relsp = rels;
1492 *nrelsp = nrels;
1493 return true;
1496 /* Returns the reloc type extracted from the reloc info field. */
1498 static unsigned int
1499 get_reloc_type (Filedata * filedata, uint64_t reloc_info)
1501 if (is_32bit_elf)
1502 return ELF32_R_TYPE (reloc_info);
1504 switch (filedata->file_header.e_machine)
1506 case EM_MIPS:
1507 /* Note: We assume that reloc_info has already been adjusted for us. */
1508 return ELF64_MIPS_R_TYPE (reloc_info);
1510 case EM_SPARCV9:
1511 return ELF64_R_TYPE_ID (reloc_info);
1513 default:
1514 return ELF64_R_TYPE (reloc_info);
1518 /* Return the symbol index extracted from the reloc info field. */
1520 static uint64_t
1521 get_reloc_symindex (uint64_t reloc_info)
1523 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1526 static inline bool
1527 uses_msp430x_relocs (Filedata * filedata)
1529 return
1530 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
1531 /* GCC uses osabi == ELFOSBI_STANDALONE. */
1532 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
1533 /* TI compiler uses ELFOSABI_NONE. */
1534 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
1538 static const char *
1539 get_symbol_at (Filedata * filedata,
1540 Elf_Internal_Sym * symtab,
1541 uint64_t nsyms,
1542 char * strtab,
1543 uint64_t where,
1544 uint64_t * offset_return)
1546 Elf_Internal_Sym * beg = symtab;
1547 Elf_Internal_Sym * end = symtab + nsyms;
1548 Elf_Internal_Sym * best = NULL;
1549 uint64_t dist = 0x100000;
1551 /* FIXME: Since this function is likely to be called repeatedly with
1552 slightly increasing addresses each time, we could speed things up by
1553 caching the last returned value and starting our search from there. */
1554 while (beg < end)
1556 Elf_Internal_Sym * sym;
1557 uint64_t value;
1559 sym = beg + (end - beg) / 2;
1561 value = sym->st_value;
1563 if (where >= value
1564 && where - value < dist)
1566 best = sym;
1567 dist = where - value;
1568 if (dist == 0)
1569 break;
1572 if (where < value)
1573 end = sym;
1574 else
1575 beg = sym + 1;
1578 const char *name;
1580 /* If there is a section start closer than the found symbol then
1581 use that for symbolizing the address. */
1582 Elf_Internal_Shdr *sec = find_section_by_address (filedata, where);
1583 if (sec != NULL
1584 && where - sec->sh_addr < dist
1585 && section_name_valid (filedata, sec))
1587 name = section_name (filedata, sec);
1588 dist = where - sec->sh_addr;
1590 else if (best != NULL)
1591 name = strtab + best->st_name;
1592 else
1593 return NULL;
1595 if (offset_return != NULL)
1596 * offset_return = dist;
1598 return name;
1601 static void
1602 print_relr_addr_and_sym (Filedata * filedata,
1603 Elf_Internal_Sym * symtab,
1604 uint64_t nsyms,
1605 char * strtab,
1606 uint64_t where)
1608 const char * symname = NULL;
1609 uint64_t offset = 0;
1611 print_vma (where, ZERO_HEX);
1612 printf (" ");
1614 symname = get_symbol_at (filedata, symtab, nsyms, strtab, where, & offset);
1616 if (symname == NULL)
1617 printf ("<no sym>");
1618 else if (offset == 0)
1619 print_symbol_name (38, symname);
1620 else
1622 print_symbol_name (28, symname);
1623 printf (" + ");
1624 print_vma (offset, PREFIX_HEX);
1628 /* See bfd_is_aarch64_special_symbol_name. */
1630 static bool
1631 is_aarch64_special_symbol_name (const char *name)
1633 if (!name || name[0] != '$')
1634 return false;
1635 if (name[1] == 'x' || name[1] == 'd')
1636 /* Map. */;
1637 else if (name[1] == 'm' || name[1] == 'f' || name[1] == 'p')
1638 /* Tag. */;
1639 else
1640 return false;
1641 return name[2] == 0 || name[2] == '.';
1644 static bool
1645 is_special_symbol_name (Filedata * filedata, const char * s)
1647 switch (filedata->file_header.e_machine)
1649 case EM_AARCH64:
1650 return is_aarch64_special_symbol_name (s);
1652 default:
1653 return false;
1657 /* Allows selecting the best symbol from a set for displaying addresses.
1658 BEST is the current best or NULL if there are no good symbols yet.
1659 SYM is the next symbol to consider, if it is better than BEST then
1660 return SYM else return BEST. */
1662 static Elf_Internal_Sym *
1663 select_display_sym (Filedata * filedata,
1664 char * strtab,
1665 uint64_t strtablen,
1666 Elf_Internal_Sym * best,
1667 Elf_Internal_Sym * sym)
1669 /* Ignore empty or invalid syms. */
1670 if (sym->st_name == 0)
1671 return best;
1672 if (sym->st_name >= strtablen)
1673 return best;
1674 /* Ignore undefined or TLS syms. */
1675 if (sym->st_shndx == SHN_UNDEF)
1676 return best;
1677 if (ELF_ST_TYPE (sym->st_info) == STT_TLS)
1678 return best;
1680 char *s = strtab + sym->st_name;
1682 /* Don't display special symbols. */
1683 if (is_special_symbol_name (filedata, s))
1684 return best;
1686 /* Here SYM is good for display. */
1688 if (best == NULL)
1689 return sym;
1691 char *sbest = strtab + best->st_name;
1693 /* Prefer non-local symbols. */
1694 if (ELF_ST_BIND (sym->st_info) == STB_LOCAL
1695 && ELF_ST_BIND (best->st_info) != STB_LOCAL)
1696 return best;
1697 if (ELF_ST_BIND (sym->st_info) != STB_LOCAL
1698 && ELF_ST_BIND (best->st_info) == STB_LOCAL)
1699 return sym;
1701 /* Select based on lexicographic order. */
1702 return strcmp (s, sbest) < 0 ? sym : best;
1705 /* Filter the sorted SYMTAB symbol array in-place to select at most one
1706 symbol for an address and drop symbols that are not good to display.
1707 Returns the new array length. */
1709 static uint64_t
1710 filter_display_syms (Filedata * filedata,
1711 Elf_Internal_Sym * symtab,
1712 uint64_t nsyms,
1713 char * strtab,
1714 uint64_t strtablen)
1716 Elf_Internal_Sym *r = symtab;
1717 Elf_Internal_Sym *w = symtab;
1718 Elf_Internal_Sym *best = NULL;
1719 Elf_Internal_Sym *end = symtab + nsyms;
1720 while (r < end)
1722 /* Select the best symbol for an address. */
1723 while (r < end
1724 && (best == NULL || best->st_value == r->st_value))
1726 best = select_display_sym (filedata, strtab, strtablen, best, r);
1727 r++;
1729 if (best != NULL)
1731 *w = *best;
1732 w++;
1733 best = NULL;
1736 return w - symtab;
1739 static /* signed */ int
1740 symcmp (const void *p, const void *q)
1742 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
1743 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
1745 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
1748 static uint64_t
1749 count_relr_relocations (Filedata * filedata,
1750 Elf_Internal_Shdr * section)
1752 uint64_t * relrs;
1753 uint64_t nentries;
1754 uint64_t i;
1755 uint64_t count;
1756 int entsize;
1758 if (section == NULL
1759 || section->sh_type != SHT_RELR
1760 || section->sh_size == 0)
1761 return 0;
1763 entsize = section->sh_entsize;
1764 if (entsize == 0)
1765 entsize = is_32bit_elf
1766 ? sizeof (Elf32_External_Relr) : sizeof (Elf64_External_Relr);
1767 else if (entsize != sizeof (Elf32_External_Relr)
1768 && entsize != sizeof (Elf64_External_Relr))
1769 return 0;
1771 nentries = section->sh_size / entsize;
1772 if (nentries == 0)
1773 return 0;
1775 /* FIXME: This call to get_data duplicates one that follows in
1776 dump_relr_relocations(). They could be combined into just
1777 one call. */
1778 relrs = get_data (NULL, filedata, section->sh_offset, 1,
1779 section->sh_size, _("RELR relocation data"));
1780 if (relrs == NULL)
1781 return 0;
1783 for (count = i = 0; i < nentries; i++)
1785 uint64_t entry;
1787 if (entsize == sizeof (Elf32_External_Relr))
1788 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1789 else
1790 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1792 if ((entry & 1) == 0)
1794 ++ count;
1796 else
1798 if (entry == 1)
1799 continue;
1801 for (; entry >>= 1;)
1802 if ((entry & 1) == 1)
1803 ++ count;
1807 free (relrs);
1808 return count;
1811 static bool
1812 dump_relr_relocations (Filedata * filedata,
1813 Elf_Internal_Shdr * section,
1814 Elf_Internal_Sym * symtab,
1815 uint64_t nsyms,
1816 char * strtab,
1817 uint64_t strtablen)
1819 uint64_t * relrs;
1820 uint64_t nentries, i;
1821 uint64_t relr_size = section->sh_size;
1822 int relr_entsize = section->sh_entsize;
1823 uint64_t relr_offset = section->sh_offset;
1824 uint64_t where = 0;
1825 int num_bits_in_entry;
1827 if (relr_entsize == 0)
1828 relr_entsize = is_32bit_elf
1829 ? sizeof (Elf32_External_Relr) : sizeof (Elf64_External_Relr);
1831 nentries = relr_size / relr_entsize;
1833 if (nentries == 0)
1834 return true;
1836 if (relr_entsize == sizeof (Elf32_External_Relr))
1837 num_bits_in_entry = 31;
1838 else if (relr_entsize == sizeof (Elf64_External_Relr))
1839 num_bits_in_entry = 63;
1840 else
1842 warn (_("Unexpected entsize for RELR section\n"));
1843 return false;
1846 relrs = get_data (NULL, filedata, relr_offset, 1, relr_size, _("RELR relocation data"));
1847 if (relrs == NULL)
1848 return false;
1850 /* Paranoia. */
1851 if (strtab == NULL)
1852 strtablen = 0;
1853 if (symtab == NULL)
1854 nsyms = 0;
1856 if (symtab != NULL)
1858 /* Symbol tables are not sorted on address, but we want a quick lookup
1859 for the symbol associated with each address computed below, so sort
1860 the table then filter out unwanted entries. FIXME: This assumes that
1861 the symbol table will not be used later on for some other purpose. */
1862 qsort (symtab, nsyms, sizeof (Elf_Internal_Sym), symcmp);
1863 nsyms = filter_display_syms (filedata, symtab, nsyms, strtab, strtablen);
1866 if (relr_entsize == sizeof (Elf32_External_Relr))
1867 printf (_ ("Index: Entry Address Symbolic Address\n"));
1868 else
1869 printf (_ ("Index: Entry Address Symbolic Address\n"));
1871 for (i = 0; i < nentries; i++)
1873 uint64_t entry;
1875 if (relr_entsize == sizeof (Elf32_External_Relr))
1876 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1877 else
1878 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1880 /* We assume that there will never be more than 9999 entries. */
1881 printf (_("%04u: "), (unsigned int) i);
1882 print_vma (entry, ZERO_HEX);
1883 printf (" ");
1885 if ((entry & 1) == 0)
1887 where = entry;
1888 print_relr_addr_and_sym (filedata, symtab, nsyms, strtab, where);
1889 printf ("\n");
1890 where += relr_entsize;
1892 else
1894 bool first = true;
1895 int j;
1897 /* The least significant bit is ignored. */
1898 if (entry == 1)
1899 /* This can actually happen when the linker is allowed to shrink
1900 RELR sections. For more details see: https://reviews.llvm.org/D67164. */
1901 continue;
1902 else if (i == 0)
1903 warn (_("Unusual RELR bitmap - no previous entry to set the base address\n"));
1905 for (j = 0; entry >>= 1; j++)
1906 if ((entry & 1) == 1)
1908 uint64_t addr = where + (j * relr_entsize);
1910 if (first)
1912 print_relr_addr_and_sym (filedata, symtab, nsyms, strtab, addr);
1913 first = false;
1915 else
1917 printf (_("\n%*s "), relr_entsize == 4 ? 15 : 23, " ");
1918 print_relr_addr_and_sym (filedata, symtab, nsyms, strtab, addr);
1922 printf ("\n");
1923 where += num_bits_in_entry * relr_entsize;
1927 free (relrs);
1928 return true;
1931 /* Display the contents of the relocation data found at the specified
1932 offset. */
1934 static bool
1935 dump_relocations (Filedata * filedata,
1936 uint64_t rel_offset,
1937 uint64_t rel_size,
1938 Elf_Internal_Sym * symtab,
1939 uint64_t nsyms,
1940 char * strtab,
1941 uint64_t strtablen,
1942 relocation_type rel_type,
1943 bool is_dynsym)
1945 size_t i;
1946 Elf_Internal_Rela * rels;
1947 bool res = true;
1949 if (rel_type == reltype_unknown)
1950 rel_type = guess_is_rela (filedata->file_header.e_machine) ? reltype_rela : reltype_rel;
1952 if (rel_type == reltype_rela)
1954 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
1955 return false;
1957 else if (rel_type == reltype_rel)
1959 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
1960 return false;
1962 else if (rel_type == reltype_relr)
1964 /* This should have been handled by display_relocations(). */
1965 return false;
1968 if (is_32bit_elf)
1970 if (rel_type == reltype_rela)
1972 if (do_wide)
1973 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1974 else
1975 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1977 else
1979 if (do_wide)
1980 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1981 else
1982 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1985 else
1987 if (rel_type == reltype_rela)
1989 if (do_wide)
1990 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
1991 else
1992 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1994 else
1996 if (do_wide)
1997 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
1998 else
1999 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
2003 for (i = 0; i < rel_size; i++)
2005 const char * rtype;
2006 uint64_t offset;
2007 uint64_t inf;
2008 uint64_t symtab_index;
2009 uint64_t type;
2011 offset = rels[i].r_offset;
2012 inf = rels[i].r_info;
2014 type = get_reloc_type (filedata, inf);
2015 symtab_index = get_reloc_symindex (inf);
2017 if (is_32bit_elf)
2019 printf ("%8.8lx %8.8lx ",
2020 (unsigned long) offset & 0xffffffff,
2021 (unsigned long) inf & 0xffffffff);
2023 else
2025 printf (do_wide
2026 ? "%16.16" PRIx64 " %16.16" PRIx64 " "
2027 : "%12.12" PRIx64 " %12.12" PRIx64 " ",
2028 offset, inf);
2031 switch (filedata->file_header.e_machine)
2033 default:
2034 rtype = NULL;
2035 break;
2037 case EM_AARCH64:
2038 rtype = elf_aarch64_reloc_type (type);
2039 break;
2041 case EM_M32R:
2042 case EM_CYGNUS_M32R:
2043 rtype = elf_m32r_reloc_type (type);
2044 break;
2046 case EM_386:
2047 case EM_IAMCU:
2048 rtype = elf_i386_reloc_type (type);
2049 break;
2051 case EM_68HC11:
2052 case EM_68HC12:
2053 rtype = elf_m68hc11_reloc_type (type);
2054 break;
2056 case EM_S12Z:
2057 rtype = elf_s12z_reloc_type (type);
2058 break;
2060 case EM_68K:
2061 rtype = elf_m68k_reloc_type (type);
2062 break;
2064 case EM_960:
2065 rtype = elf_i960_reloc_type (type);
2066 break;
2068 case EM_AVR:
2069 case EM_AVR_OLD:
2070 rtype = elf_avr_reloc_type (type);
2071 break;
2073 case EM_OLD_SPARCV9:
2074 case EM_SPARC32PLUS:
2075 case EM_SPARCV9:
2076 case EM_SPARC:
2077 rtype = elf_sparc_reloc_type (type);
2078 break;
2080 case EM_SPU:
2081 rtype = elf_spu_reloc_type (type);
2082 break;
2084 case EM_V800:
2085 rtype = v800_reloc_type (type);
2086 break;
2087 case EM_V850:
2088 case EM_CYGNUS_V850:
2089 rtype = v850_reloc_type (type);
2090 break;
2092 case EM_D10V:
2093 case EM_CYGNUS_D10V:
2094 rtype = elf_d10v_reloc_type (type);
2095 break;
2097 case EM_D30V:
2098 case EM_CYGNUS_D30V:
2099 rtype = elf_d30v_reloc_type (type);
2100 break;
2102 case EM_DLX:
2103 rtype = elf_dlx_reloc_type (type);
2104 break;
2106 case EM_SH:
2107 rtype = elf_sh_reloc_type (type);
2108 break;
2110 case EM_MN10300:
2111 case EM_CYGNUS_MN10300:
2112 rtype = elf_mn10300_reloc_type (type);
2113 break;
2115 case EM_MN10200:
2116 case EM_CYGNUS_MN10200:
2117 rtype = elf_mn10200_reloc_type (type);
2118 break;
2120 case EM_FR30:
2121 case EM_CYGNUS_FR30:
2122 rtype = elf_fr30_reloc_type (type);
2123 break;
2125 case EM_CYGNUS_FRV:
2126 rtype = elf_frv_reloc_type (type);
2127 break;
2129 case EM_CSKY:
2130 rtype = elf_csky_reloc_type (type);
2131 break;
2133 case EM_FT32:
2134 rtype = elf_ft32_reloc_type (type);
2135 break;
2137 case EM_MCORE:
2138 rtype = elf_mcore_reloc_type (type);
2139 break;
2141 case EM_MMIX:
2142 rtype = elf_mmix_reloc_type (type);
2143 break;
2145 case EM_MOXIE:
2146 rtype = elf_moxie_reloc_type (type);
2147 break;
2149 case EM_MSP430:
2150 if (uses_msp430x_relocs (filedata))
2152 rtype = elf_msp430x_reloc_type (type);
2153 break;
2155 /* Fall through. */
2156 case EM_MSP430_OLD:
2157 rtype = elf_msp430_reloc_type (type);
2158 break;
2160 case EM_NDS32:
2161 rtype = elf_nds32_reloc_type (type);
2162 break;
2164 case EM_PPC:
2165 rtype = elf_ppc_reloc_type (type);
2166 break;
2168 case EM_PPC64:
2169 rtype = elf_ppc64_reloc_type (type);
2170 break;
2172 case EM_MIPS:
2173 case EM_MIPS_RS3_LE:
2174 rtype = elf_mips_reloc_type (type);
2175 break;
2177 case EM_RISCV:
2178 rtype = elf_riscv_reloc_type (type);
2179 break;
2181 case EM_ALPHA:
2182 rtype = elf_alpha_reloc_type (type);
2183 break;
2185 case EM_ARM:
2186 rtype = elf_arm_reloc_type (type);
2187 break;
2189 case EM_ARC:
2190 case EM_ARC_COMPACT:
2191 case EM_ARC_COMPACT2:
2192 case EM_ARC_COMPACT3:
2193 case EM_ARC_COMPACT3_64:
2194 rtype = elf_arc_reloc_type (type);
2195 break;
2197 case EM_PARISC:
2198 rtype = elf_hppa_reloc_type (type);
2199 break;
2201 case EM_H8_300:
2202 case EM_H8_300H:
2203 case EM_H8S:
2204 rtype = elf_h8_reloc_type (type);
2205 break;
2207 case EM_OR1K:
2208 rtype = elf_or1k_reloc_type (type);
2209 break;
2211 case EM_PJ:
2212 case EM_PJ_OLD:
2213 rtype = elf_pj_reloc_type (type);
2214 break;
2215 case EM_IA_64:
2216 rtype = elf_ia64_reloc_type (type);
2217 break;
2219 case EM_KVX:
2220 rtype = elf_kvx_reloc_type (type);
2221 break;
2223 case EM_CRIS:
2224 rtype = elf_cris_reloc_type (type);
2225 break;
2227 case EM_860:
2228 rtype = elf_i860_reloc_type (type);
2229 break;
2231 case EM_X86_64:
2232 case EM_L1OM:
2233 case EM_K1OM:
2234 rtype = elf_x86_64_reloc_type (type);
2235 break;
2237 case EM_S370:
2238 rtype = i370_reloc_type (type);
2239 break;
2241 case EM_S390_OLD:
2242 case EM_S390:
2243 rtype = elf_s390_reloc_type (type);
2244 break;
2246 case EM_SCORE:
2247 rtype = elf_score_reloc_type (type);
2248 break;
2250 case EM_XSTORMY16:
2251 rtype = elf_xstormy16_reloc_type (type);
2252 break;
2254 case EM_CRX:
2255 rtype = elf_crx_reloc_type (type);
2256 break;
2258 case EM_VAX:
2259 rtype = elf_vax_reloc_type (type);
2260 break;
2262 case EM_VISIUM:
2263 rtype = elf_visium_reloc_type (type);
2264 break;
2266 case EM_BPF:
2267 rtype = elf_bpf_reloc_type (type);
2268 break;
2270 case EM_ADAPTEVA_EPIPHANY:
2271 rtype = elf_epiphany_reloc_type (type);
2272 break;
2274 case EM_IP2K:
2275 case EM_IP2K_OLD:
2276 rtype = elf_ip2k_reloc_type (type);
2277 break;
2279 case EM_IQ2000:
2280 rtype = elf_iq2000_reloc_type (type);
2281 break;
2283 case EM_XTENSA_OLD:
2284 case EM_XTENSA:
2285 rtype = elf_xtensa_reloc_type (type);
2286 break;
2288 case EM_LATTICEMICO32:
2289 rtype = elf_lm32_reloc_type (type);
2290 break;
2292 case EM_M32C_OLD:
2293 case EM_M32C:
2294 rtype = elf_m32c_reloc_type (type);
2295 break;
2297 case EM_MT:
2298 rtype = elf_mt_reloc_type (type);
2299 break;
2301 case EM_BLACKFIN:
2302 rtype = elf_bfin_reloc_type (type);
2303 break;
2305 case EM_CYGNUS_MEP:
2306 rtype = elf_mep_reloc_type (type);
2307 break;
2309 case EM_CR16:
2310 rtype = elf_cr16_reloc_type (type);
2311 break;
2313 case EM_MICROBLAZE:
2314 case EM_MICROBLAZE_OLD:
2315 rtype = elf_microblaze_reloc_type (type);
2316 break;
2318 case EM_RL78:
2319 rtype = elf_rl78_reloc_type (type);
2320 break;
2322 case EM_RX:
2323 rtype = elf_rx_reloc_type (type);
2324 break;
2326 case EM_METAG:
2327 rtype = elf_metag_reloc_type (type);
2328 break;
2330 case EM_TI_C6000:
2331 rtype = elf_tic6x_reloc_type (type);
2332 break;
2334 case EM_TILEGX:
2335 rtype = elf_tilegx_reloc_type (type);
2336 break;
2338 case EM_TILEPRO:
2339 rtype = elf_tilepro_reloc_type (type);
2340 break;
2342 case EM_WEBASSEMBLY:
2343 rtype = elf_wasm32_reloc_type (type);
2344 break;
2346 case EM_XGATE:
2347 rtype = elf_xgate_reloc_type (type);
2348 break;
2350 case EM_ALTERA_NIOS2:
2351 rtype = elf_nios2_reloc_type (type);
2352 break;
2354 case EM_TI_PRU:
2355 rtype = elf_pru_reloc_type (type);
2356 break;
2358 case EM_NFP:
2359 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
2360 rtype = elf_nfp3200_reloc_type (type);
2361 else
2362 rtype = elf_nfp_reloc_type (type);
2363 break;
2365 case EM_Z80:
2366 rtype = elf_z80_reloc_type (type);
2367 break;
2369 case EM_LOONGARCH:
2370 rtype = elf_loongarch_reloc_type (type);
2371 break;
2373 case EM_AMDGPU:
2374 rtype = elf_amdgpu_reloc_type (type);
2375 break;
2378 if (rtype == NULL)
2379 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
2380 else
2381 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
2383 if (filedata->file_header.e_machine == EM_ALPHA
2384 && rtype != NULL
2385 && streq (rtype, "R_ALPHA_LITUSE")
2386 && rel_type == reltype_rela)
2388 switch (rels[i].r_addend)
2390 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
2391 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
2392 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
2393 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
2394 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
2395 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
2396 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
2397 default: rtype = NULL;
2400 if (rtype)
2401 printf (" (%s)", rtype);
2402 else
2404 putchar (' ');
2405 printf (_("<unknown addend: %" PRIx64 ">"),
2406 rels[i].r_addend);
2407 res = false;
2410 else if (symtab_index)
2412 if (symtab == NULL || symtab_index >= nsyms)
2414 error (_(" bad symbol index: %08lx in reloc\n"),
2415 (unsigned long) symtab_index);
2416 res = false;
2418 else
2420 Elf_Internal_Sym * psym;
2421 const char * version_string;
2422 enum versioned_symbol_info sym_info;
2423 unsigned short vna_other;
2425 psym = symtab + symtab_index;
2427 version_string
2428 = get_symbol_version_string (filedata, is_dynsym,
2429 strtab, strtablen,
2430 symtab_index,
2431 psym,
2432 &sym_info,
2433 &vna_other);
2435 printf (" ");
2437 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
2439 const char * name;
2440 unsigned int len;
2441 unsigned int width = is_32bit_elf ? 8 : 14;
2443 /* Relocations against GNU_IFUNC symbols do not use the value
2444 of the symbol as the address to relocate against. Instead
2445 they invoke the function named by the symbol and use its
2446 result as the address for relocation.
2448 To indicate this to the user, do not display the value of
2449 the symbol in the "Symbols's Value" field. Instead show
2450 its name followed by () as a hint that the symbol is
2451 invoked. */
2453 if (strtab == NULL
2454 || psym->st_name == 0
2455 || psym->st_name >= strtablen)
2456 name = "??";
2457 else
2458 name = strtab + psym->st_name;
2460 len = print_symbol_name (width, name);
2461 if (version_string)
2462 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2463 version_string);
2464 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
2466 else
2468 print_vma (psym->st_value, LONG_HEX);
2470 printf (is_32bit_elf ? " " : " ");
2473 if (psym->st_name == 0)
2475 const char * sec_name = "<null>";
2477 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
2478 sec_name = printable_section_name_from_index
2479 (filedata, psym->st_shndx, NULL);
2481 print_symbol_name (22, sec_name);
2483 else if (strtab == NULL)
2484 printf (_("<string table index: %3ld>"), psym->st_name);
2485 else if (psym->st_name >= strtablen)
2487 error (_("<corrupt string table index: %3ld>\n"),
2488 psym->st_name);
2489 res = false;
2491 else
2493 print_symbol_name (22, strtab + psym->st_name);
2494 if (version_string)
2495 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2496 version_string);
2499 if (rel_type == reltype_rela)
2501 uint64_t off = rels[i].r_addend;
2503 if ((int64_t) off < 0)
2504 printf (" - %" PRIx64, -off);
2505 else
2506 printf (" + %" PRIx64, off);
2510 else if (rel_type == reltype_rela)
2512 uint64_t off = rels[i].r_addend;
2514 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
2515 if ((int64_t) off < 0)
2516 printf ("-%" PRIx64, -off);
2517 else
2518 printf ("%" PRIx64, off);
2521 if (filedata->file_header.e_machine == EM_SPARCV9
2522 && rtype != NULL
2523 && streq (rtype, "R_SPARC_OLO10"))
2524 printf (" + %" PRIx64, ELF64_R_TYPE_DATA (inf));
2526 putchar ('\n');
2528 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2530 uint64_t type2 = ELF64_MIPS_R_TYPE2 (inf);
2531 uint64_t type3 = ELF64_MIPS_R_TYPE3 (inf);
2532 const char * rtype2 = elf_mips_reloc_type (type2);
2533 const char * rtype3 = elf_mips_reloc_type (type3);
2535 printf (" Type2: ");
2537 if (rtype2 == NULL)
2538 printf (_("unrecognized: %-7lx"),
2539 (unsigned long) type2 & 0xffffffff);
2540 else
2541 printf ("%-17.17s", rtype2);
2543 printf ("\n Type3: ");
2545 if (rtype3 == NULL)
2546 printf (_("unrecognized: %-7lx"),
2547 (unsigned long) type3 & 0xffffffff);
2548 else
2549 printf ("%-17.17s", rtype3);
2551 putchar ('\n');
2555 free (rels);
2557 return res;
2560 static const char *
2561 get_aarch64_dynamic_type (unsigned long type)
2563 switch (type)
2565 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
2566 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2567 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
2568 default:
2569 return NULL;
2573 static const char *
2574 get_mips_dynamic_type (unsigned long type)
2576 switch (type)
2578 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
2579 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
2580 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
2581 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
2582 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
2583 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
2584 case DT_MIPS_MSYM: return "MIPS_MSYM";
2585 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2586 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2587 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
2588 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
2589 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
2590 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
2591 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
2592 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
2593 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
2594 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
2595 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
2596 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
2597 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
2598 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
2599 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
2600 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
2601 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
2602 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
2603 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
2604 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
2605 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
2606 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
2607 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
2608 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2609 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
2610 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
2611 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
2612 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
2613 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2614 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
2615 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
2616 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
2617 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
2618 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
2619 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
2620 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
2621 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
2622 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
2623 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
2624 case DT_MIPS_XHASH: return "MIPS_XHASH";
2625 default:
2626 return NULL;
2630 static const char *
2631 get_sparc64_dynamic_type (unsigned long type)
2633 switch (type)
2635 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
2636 default:
2637 return NULL;
2641 static const char *
2642 get_ppc_dynamic_type (unsigned long type)
2644 switch (type)
2646 case DT_PPC_GOT: return "PPC_GOT";
2647 case DT_PPC_OPT: return "PPC_OPT";
2648 default:
2649 return NULL;
2653 static const char *
2654 get_ppc64_dynamic_type (unsigned long type)
2656 switch (type)
2658 case DT_PPC64_GLINK: return "PPC64_GLINK";
2659 case DT_PPC64_OPD: return "PPC64_OPD";
2660 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
2661 case DT_PPC64_OPT: return "PPC64_OPT";
2662 default:
2663 return NULL;
2667 static const char *
2668 get_parisc_dynamic_type (unsigned long type)
2670 switch (type)
2672 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
2673 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
2674 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
2675 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
2676 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
2677 case DT_HP_PREINIT: return "HP_PREINIT";
2678 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
2679 case DT_HP_NEEDED: return "HP_NEEDED";
2680 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
2681 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2682 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2683 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2684 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
2685 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2686 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2687 case DT_HP_FILTERED: return "HP_FILTERED";
2688 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2689 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2690 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2691 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2692 case DT_PLT: return "PLT";
2693 case DT_PLT_SIZE: return "PLT_SIZE";
2694 case DT_DLT: return "DLT";
2695 case DT_DLT_SIZE: return "DLT_SIZE";
2696 default:
2697 return NULL;
2701 static const char *
2702 get_ia64_dynamic_type (unsigned long type)
2704 switch (type)
2706 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2707 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2708 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2709 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2710 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2711 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2712 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2713 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2714 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2715 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2716 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2717 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2718 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2719 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2720 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2721 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2722 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2723 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2724 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2725 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2726 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2727 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2728 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2729 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2730 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2731 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2732 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2733 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2734 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2735 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2736 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
2737 default:
2738 return NULL;
2742 static const char *
2743 get_solaris_section_type (unsigned long type)
2745 switch (type)
2747 case 0x6fffffee: return "SUNW_ancillary";
2748 case 0x6fffffef: return "SUNW_capchain";
2749 case 0x6ffffff0: return "SUNW_capinfo";
2750 case 0x6ffffff1: return "SUNW_symsort";
2751 case 0x6ffffff2: return "SUNW_tlssort";
2752 case 0x6ffffff3: return "SUNW_LDYNSYM";
2753 case 0x6ffffff4: return "SUNW_dof";
2754 case 0x6ffffff5: return "SUNW_cap";
2755 case 0x6ffffff6: return "SUNW_SIGNATURE";
2756 case 0x6ffffff7: return "SUNW_ANNOTATE";
2757 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2758 case 0x6ffffff9: return "SUNW_DEBUG";
2759 case 0x6ffffffa: return "SUNW_move";
2760 case 0x6ffffffb: return "SUNW_COMDAT";
2761 case 0x6ffffffc: return "SUNW_syminfo";
2762 case 0x6ffffffd: return "SUNW_verdef";
2763 case 0x6ffffffe: return "SUNW_verneed";
2764 case 0x6fffffff: return "SUNW_versym";
2765 case 0x70000000: return "SPARC_GOTDATA";
2766 default: return NULL;
2770 static const char *
2771 get_alpha_dynamic_type (unsigned long type)
2773 switch (type)
2775 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
2776 default: return NULL;
2780 static const char *
2781 get_score_dynamic_type (unsigned long type)
2783 switch (type)
2785 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2786 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2787 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2788 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2789 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2790 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
2791 default: return NULL;
2795 static const char *
2796 get_tic6x_dynamic_type (unsigned long type)
2798 switch (type)
2800 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2801 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2802 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2803 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2804 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2805 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
2806 default: return NULL;
2810 static const char *
2811 get_nios2_dynamic_type (unsigned long type)
2813 switch (type)
2815 case DT_NIOS2_GP: return "NIOS2_GP";
2816 default: return NULL;
2820 static const char *
2821 get_solaris_dynamic_type (unsigned long type)
2823 switch (type)
2825 case 0x6000000d: return "SUNW_AUXILIARY";
2826 case 0x6000000e: return "SUNW_RTLDINF";
2827 case 0x6000000f: return "SUNW_FILTER";
2828 case 0x60000010: return "SUNW_CAP";
2829 case 0x60000011: return "SUNW_SYMTAB";
2830 case 0x60000012: return "SUNW_SYMSZ";
2831 case 0x60000013: return "SUNW_SORTENT";
2832 case 0x60000014: return "SUNW_SYMSORT";
2833 case 0x60000015: return "SUNW_SYMSORTSZ";
2834 case 0x60000016: return "SUNW_TLSSORT";
2835 case 0x60000017: return "SUNW_TLSSORTSZ";
2836 case 0x60000018: return "SUNW_CAPINFO";
2837 case 0x60000019: return "SUNW_STRPAD";
2838 case 0x6000001a: return "SUNW_CAPCHAIN";
2839 case 0x6000001b: return "SUNW_LDMACH";
2840 case 0x6000001d: return "SUNW_CAPCHAINENT";
2841 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2842 case 0x60000021: return "SUNW_PARENT";
2843 case 0x60000023: return "SUNW_ASLR";
2844 case 0x60000025: return "SUNW_RELAX";
2845 case 0x60000029: return "SUNW_NXHEAP";
2846 case 0x6000002b: return "SUNW_NXSTACK";
2848 case 0x70000001: return "SPARC_REGISTER";
2849 case 0x7ffffffd: return "AUXILIARY";
2850 case 0x7ffffffe: return "USED";
2851 case 0x7fffffff: return "FILTER";
2853 default: return NULL;
2857 static const char *
2858 get_riscv_dynamic_type (unsigned long type)
2860 switch (type)
2862 case DT_RISCV_VARIANT_CC: return "RISCV_VARIANT_CC";
2863 default:
2864 return NULL;
2868 static const char *
2869 get_x86_64_dynamic_type (unsigned long type)
2871 switch (type)
2873 case DT_X86_64_PLT:
2874 return "DT_X86_64_PLT";
2875 case DT_X86_64_PLTSZ:
2876 return "DT_X86_64_PLTSZ";
2877 case DT_X86_64_PLTENT:
2878 return "DT_X86_64_PLTENT";
2879 default:
2880 return NULL;
2884 static const char *
2885 get_dynamic_type (Filedata * filedata, unsigned long type)
2887 static char buff[64];
2889 switch (type)
2891 case DT_NULL: return "NULL";
2892 case DT_NEEDED: return "NEEDED";
2893 case DT_PLTRELSZ: return "PLTRELSZ";
2894 case DT_PLTGOT: return "PLTGOT";
2895 case DT_HASH: return "HASH";
2896 case DT_STRTAB: return "STRTAB";
2897 case DT_SYMTAB: return "SYMTAB";
2898 case DT_RELA: return "RELA";
2899 case DT_RELASZ: return "RELASZ";
2900 case DT_RELAENT: return "RELAENT";
2901 case DT_STRSZ: return "STRSZ";
2902 case DT_SYMENT: return "SYMENT";
2903 case DT_INIT: return "INIT";
2904 case DT_FINI: return "FINI";
2905 case DT_SONAME: return "SONAME";
2906 case DT_RPATH: return "RPATH";
2907 case DT_SYMBOLIC: return "SYMBOLIC";
2908 case DT_REL: return "REL";
2909 case DT_RELSZ: return "RELSZ";
2910 case DT_RELENT: return "RELENT";
2911 case DT_RELR: return "RELR";
2912 case DT_RELRSZ: return "RELRSZ";
2913 case DT_RELRENT: return "RELRENT";
2914 case DT_PLTREL: return "PLTREL";
2915 case DT_DEBUG: return "DEBUG";
2916 case DT_TEXTREL: return "TEXTREL";
2917 case DT_JMPREL: return "JMPREL";
2918 case DT_BIND_NOW: return "BIND_NOW";
2919 case DT_INIT_ARRAY: return "INIT_ARRAY";
2920 case DT_FINI_ARRAY: return "FINI_ARRAY";
2921 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2922 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
2923 case DT_RUNPATH: return "RUNPATH";
2924 case DT_FLAGS: return "FLAGS";
2926 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2927 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
2928 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
2930 case DT_CHECKSUM: return "CHECKSUM";
2931 case DT_PLTPADSZ: return "PLTPADSZ";
2932 case DT_MOVEENT: return "MOVEENT";
2933 case DT_MOVESZ: return "MOVESZ";
2934 case DT_FEATURE: return "FEATURE";
2935 case DT_POSFLAG_1: return "POSFLAG_1";
2936 case DT_SYMINSZ: return "SYMINSZ";
2937 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
2939 case DT_ADDRRNGLO: return "ADDRRNGLO";
2940 case DT_CONFIG: return "CONFIG";
2941 case DT_DEPAUDIT: return "DEPAUDIT";
2942 case DT_AUDIT: return "AUDIT";
2943 case DT_PLTPAD: return "PLTPAD";
2944 case DT_MOVETAB: return "MOVETAB";
2945 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
2947 case DT_VERSYM: return "VERSYM";
2949 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2950 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
2951 case DT_RELACOUNT: return "RELACOUNT";
2952 case DT_RELCOUNT: return "RELCOUNT";
2953 case DT_FLAGS_1: return "FLAGS_1";
2954 case DT_VERDEF: return "VERDEF";
2955 case DT_VERDEFNUM: return "VERDEFNUM";
2956 case DT_VERNEED: return "VERNEED";
2957 case DT_VERNEEDNUM: return "VERNEEDNUM";
2959 case DT_AUXILIARY: return "AUXILIARY";
2960 case DT_USED: return "USED";
2961 case DT_FILTER: return "FILTER";
2963 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2964 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2965 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2966 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2967 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
2968 case DT_GNU_HASH: return "GNU_HASH";
2969 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
2971 default:
2972 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2974 const char * result;
2976 switch (filedata->file_header.e_machine)
2978 case EM_AARCH64:
2979 result = get_aarch64_dynamic_type (type);
2980 break;
2981 case EM_MIPS:
2982 case EM_MIPS_RS3_LE:
2983 result = get_mips_dynamic_type (type);
2984 break;
2985 case EM_SPARCV9:
2986 result = get_sparc64_dynamic_type (type);
2987 break;
2988 case EM_PPC:
2989 result = get_ppc_dynamic_type (type);
2990 break;
2991 case EM_PPC64:
2992 result = get_ppc64_dynamic_type (type);
2993 break;
2994 case EM_IA_64:
2995 result = get_ia64_dynamic_type (type);
2996 break;
2997 case EM_ALPHA:
2998 result = get_alpha_dynamic_type (type);
2999 break;
3000 case EM_SCORE:
3001 result = get_score_dynamic_type (type);
3002 break;
3003 case EM_TI_C6000:
3004 result = get_tic6x_dynamic_type (type);
3005 break;
3006 case EM_ALTERA_NIOS2:
3007 result = get_nios2_dynamic_type (type);
3008 break;
3009 case EM_RISCV:
3010 result = get_riscv_dynamic_type (type);
3011 break;
3012 case EM_X86_64:
3013 result = get_x86_64_dynamic_type (type);
3014 break;
3015 default:
3016 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
3017 result = get_solaris_dynamic_type (type);
3018 else
3019 result = NULL;
3020 break;
3023 if (result != NULL)
3024 return result;
3026 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
3028 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
3029 || (filedata->file_header.e_machine == EM_PARISC
3030 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
3032 const char * result;
3034 switch (filedata->file_header.e_machine)
3036 case EM_PARISC:
3037 result = get_parisc_dynamic_type (type);
3038 break;
3039 case EM_IA_64:
3040 result = get_ia64_dynamic_type (type);
3041 break;
3042 default:
3043 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
3044 result = get_solaris_dynamic_type (type);
3045 else
3046 result = NULL;
3047 break;
3050 if (result != NULL)
3051 return result;
3053 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
3054 type);
3056 else
3057 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
3059 return buff;
3063 static bool get_program_headers (Filedata *);
3064 static bool get_dynamic_section (Filedata *);
3066 static void
3067 locate_dynamic_section (Filedata *filedata)
3069 uint64_t dynamic_addr = 0;
3070 uint64_t dynamic_size = 0;
3072 if (filedata->file_header.e_phnum != 0
3073 && get_program_headers (filedata))
3075 Elf_Internal_Phdr *segment;
3076 unsigned int i;
3078 for (i = 0, segment = filedata->program_headers;
3079 i < filedata->file_header.e_phnum;
3080 i++, segment++)
3082 if (segment->p_type == PT_DYNAMIC)
3084 dynamic_addr = segment->p_offset;
3085 dynamic_size = segment->p_filesz;
3087 if (filedata->section_headers != NULL)
3089 Elf_Internal_Shdr *sec;
3091 sec = find_section (filedata, ".dynamic");
3092 if (sec != NULL)
3094 if (sec->sh_size == 0
3095 || sec->sh_type == SHT_NOBITS)
3097 dynamic_addr = 0;
3098 dynamic_size = 0;
3100 else
3102 dynamic_addr = sec->sh_offset;
3103 dynamic_size = sec->sh_size;
3108 if (dynamic_addr > filedata->file_size
3109 || (dynamic_size > filedata->file_size - dynamic_addr))
3111 dynamic_addr = 0;
3112 dynamic_size = 0;
3114 break;
3118 filedata->dynamic_addr = dynamic_addr;
3119 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
3122 static bool
3123 is_pie (Filedata *filedata)
3125 Elf_Internal_Dyn *entry;
3127 if (filedata->dynamic_size == 0)
3128 locate_dynamic_section (filedata);
3129 if (filedata->dynamic_size <= 1)
3130 return false;
3132 if (!get_dynamic_section (filedata))
3133 return false;
3135 for (entry = filedata->dynamic_section;
3136 entry < filedata->dynamic_section + filedata->dynamic_nent;
3137 entry++)
3139 if (entry->d_tag == DT_FLAGS_1)
3141 if ((entry->d_un.d_val & DF_1_PIE) != 0)
3142 return true;
3143 break;
3146 return false;
3149 static char *
3150 get_file_type (Filedata *filedata)
3152 unsigned e_type = filedata->file_header.e_type;
3153 static char buff[64];
3155 switch (e_type)
3157 case ET_NONE: return _("NONE (None)");
3158 case ET_REL: return _("REL (Relocatable file)");
3159 case ET_EXEC: return _("EXEC (Executable file)");
3160 case ET_DYN:
3161 if (is_pie (filedata))
3162 return _("DYN (Position-Independent Executable file)");
3163 else
3164 return _("DYN (Shared object file)");
3165 case ET_CORE: return _("CORE (Core file)");
3167 default:
3168 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
3169 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
3170 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
3171 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
3172 else
3173 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
3174 return buff;
3178 static char *
3179 get_machine_name (unsigned e_machine)
3181 static char buff[64]; /* XXX */
3183 switch (e_machine)
3185 /* Please keep this switch table sorted by increasing EM_ value. */
3186 /* 0 */
3187 case EM_NONE: return _("None");
3188 case EM_M32: return "WE32100";
3189 case EM_SPARC: return "Sparc";
3190 case EM_386: return "Intel 80386";
3191 case EM_68K: return "MC68000";
3192 case EM_88K: return "MC88000";
3193 case EM_IAMCU: return "Intel MCU";
3194 case EM_860: return "Intel 80860";
3195 case EM_MIPS: return "MIPS R3000";
3196 case EM_S370: return "IBM System/370";
3197 /* 10 */
3198 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
3199 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
3200 case EM_PARISC: return "HPPA";
3201 case EM_VPP550: return "Fujitsu VPP500";
3202 case EM_SPARC32PLUS: return "Sparc v8+" ;
3203 case EM_960: return "Intel 80960";
3204 case EM_PPC: return "PowerPC";
3205 /* 20 */
3206 case EM_PPC64: return "PowerPC64";
3207 case EM_S390_OLD:
3208 case EM_S390: return "IBM S/390";
3209 case EM_SPU: return "SPU";
3210 /* 30 */
3211 case EM_V800: return "Renesas V850 (using RH850 ABI)";
3212 case EM_FR20: return "Fujitsu FR20";
3213 case EM_RH32: return "TRW RH32";
3214 case EM_MCORE: return "MCORE";
3215 /* 40 */
3216 case EM_ARM: return "ARM";
3217 case EM_OLD_ALPHA: return "Digital Alpha (old)";
3218 case EM_SH: return "Renesas / SuperH SH";
3219 case EM_SPARCV9: return "Sparc v9";
3220 case EM_TRICORE: return "Siemens Tricore";
3221 case EM_ARC: return "ARC";
3222 case EM_H8_300: return "Renesas H8/300";
3223 case EM_H8_300H: return "Renesas H8/300H";
3224 case EM_H8S: return "Renesas H8S";
3225 case EM_H8_500: return "Renesas H8/500";
3226 /* 50 */
3227 case EM_IA_64: return "Intel IA-64";
3228 case EM_MIPS_X: return "Stanford MIPS-X";
3229 case EM_COLDFIRE: return "Motorola Coldfire";
3230 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
3231 case EM_MMA: return "Fujitsu Multimedia Accelerator";
3232 case EM_PCP: return "Siemens PCP";
3233 case EM_NCPU: return "Sony nCPU embedded RISC processor";
3234 case EM_NDR1: return "Denso NDR1 microprocessor";
3235 case EM_STARCORE: return "Motorola Star*Core processor";
3236 case EM_ME16: return "Toyota ME16 processor";
3237 /* 60 */
3238 case EM_ST100: return "STMicroelectronics ST100 processor";
3239 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
3240 case EM_X86_64: return "Advanced Micro Devices X86-64";
3241 case EM_PDSP: return "Sony DSP processor";
3242 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
3243 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
3244 case EM_FX66: return "Siemens FX66 microcontroller";
3245 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
3246 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
3247 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
3248 /* 70 */
3249 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
3250 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
3251 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
3252 case EM_SVX: return "Silicon Graphics SVx";
3253 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
3254 case EM_VAX: return "Digital VAX";
3255 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
3256 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
3257 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
3258 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
3259 /* 80 */
3260 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
3261 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3262 case EM_PRISM: return "Vitesse Prism";
3263 case EM_AVR_OLD:
3264 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
3265 case EM_CYGNUS_FR30:
3266 case EM_FR30: return "Fujitsu FR30";
3267 case EM_CYGNUS_D10V:
3268 case EM_D10V: return "d10v";
3269 case EM_CYGNUS_D30V:
3270 case EM_D30V: return "d30v";
3271 case EM_CYGNUS_V850:
3272 case EM_V850: return "Renesas V850";
3273 case EM_CYGNUS_M32R:
3274 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
3275 case EM_CYGNUS_MN10300:
3276 case EM_MN10300: return "mn10300";
3277 /* 90 */
3278 case EM_CYGNUS_MN10200:
3279 case EM_MN10200: return "mn10200";
3280 case EM_PJ: return "picoJava";
3281 case EM_OR1K: return "OpenRISC 1000";
3282 case EM_ARC_COMPACT: return "ARCompact";
3283 case EM_XTENSA_OLD:
3284 case EM_XTENSA: return "Tensilica Xtensa Processor";
3285 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
3286 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
3287 case EM_NS32K: return "National Semiconductor 32000 series";
3288 case EM_TPC: return "Tenor Network TPC processor";
3289 case EM_SNP1K: return "Trebia SNP 1000 processor";
3290 /* 100 */
3291 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
3292 case EM_IP2K_OLD:
3293 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3294 case EM_MAX: return "MAX Processor";
3295 case EM_CR: return "National Semiconductor CompactRISC";
3296 case EM_F2MC16: return "Fujitsu F2MC16";
3297 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
3298 case EM_BLACKFIN: return "Analog Devices Blackfin";
3299 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
3300 case EM_SEP: return "Sharp embedded microprocessor";
3301 case EM_ARCA: return "Arca RISC microprocessor";
3302 /* 110 */
3303 case EM_UNICORE: return "Unicore";
3304 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
3305 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
3306 case EM_ALTERA_NIOS2: return "Altera Nios II";
3307 case EM_CRX: return "National Semiconductor CRX microprocessor";
3308 case EM_XGATE: return "Motorola XGATE embedded processor";
3309 case EM_C166:
3310 case EM_XC16X: return "Infineon Technologies xc16x";
3311 case EM_M16C: return "Renesas M16C series microprocessors";
3312 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
3313 case EM_CE: return "Freescale Communication Engine RISC core";
3314 /* 120 */
3315 case EM_M32C: return "Renesas M32c";
3316 /* 130 */
3317 case EM_TSK3000: return "Altium TSK3000 core";
3318 case EM_RS08: return "Freescale RS08 embedded processor";
3319 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
3320 case EM_SCORE: return "SUNPLUS S+Core";
3321 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
3322 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
3323 case EM_LATTICEMICO32: return "Lattice Mico32";
3324 case EM_SE_C17: return "Seiko Epson C17 family";
3325 /* 140 */
3326 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
3327 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
3328 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
3329 case EM_TI_PRU: return "TI PRU I/O processor";
3330 /* 160 */
3331 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
3332 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
3333 case EM_R32C: return "Renesas R32C series microprocessors";
3334 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
3335 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
3336 case EM_8051: return "Intel 8051 and variants";
3337 case EM_STXP7X: return "STMicroelectronics STxP7x family";
3338 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
3339 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
3340 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
3341 /* 170 */
3342 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
3343 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
3344 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
3345 case EM_RX: return "Renesas RX";
3346 case EM_METAG: return "Imagination Technologies Meta processor architecture";
3347 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
3348 case EM_ECOG16: return "Cyan Technology eCOG16 family";
3349 case EM_CR16:
3350 case EM_MICROBLAZE:
3351 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
3352 case EM_ETPU: return "Freescale Extended Time Processing Unit";
3353 case EM_SLE9X: return "Infineon Technologies SLE9X core";
3354 /* 180 */
3355 case EM_L1OM: return "Intel L1OM";
3356 case EM_K1OM: return "Intel K1OM";
3357 case EM_INTEL182: return "Intel (reserved)";
3358 case EM_AARCH64: return "AArch64";
3359 case EM_ARM184: return "ARM (reserved)";
3360 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
3361 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
3362 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
3363 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
3364 /* 190 */
3365 case EM_CUDA: return "NVIDIA CUDA architecture";
3366 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
3367 case EM_CLOUDSHIELD: return "CloudShield architecture family";
3368 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
3369 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
3370 case EM_ARC_COMPACT2: return "ARCv2";
3371 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
3372 case EM_RL78: return "Renesas RL78";
3373 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
3374 case EM_78K0R: return "Renesas 78K0R";
3375 /* 200 */
3376 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
3377 case EM_BA1: return "Beyond BA1 CPU architecture";
3378 case EM_BA2: return "Beyond BA2 CPU architecture";
3379 case EM_XCORE: return "XMOS xCORE processor family";
3380 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
3381 case EM_INTELGT: return "Intel Graphics Technology";
3382 /* 210 */
3383 case EM_KM32: return "KM211 KM32 32-bit processor";
3384 case EM_KMX32: return "KM211 KMX32 32-bit processor";
3385 case EM_KMX16: return "KM211 KMX16 16-bit processor";
3386 case EM_KMX8: return "KM211 KMX8 8-bit processor";
3387 case EM_KVARC: return "KM211 KVARC processor";
3388 case EM_CDP: return "Paneve CDP architecture family";
3389 case EM_COGE: return "Cognitive Smart Memory Processor";
3390 case EM_COOL: return "Bluechip Systems CoolEngine";
3391 case EM_NORC: return "Nanoradio Optimized RISC";
3392 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
3393 /* 220 */
3394 case EM_Z80: return "Zilog Z80";
3395 case EM_VISIUM: return "CDS VISIUMcore processor";
3396 case EM_FT32: return "FTDI Chip FT32";
3397 case EM_MOXIE: return "Moxie";
3398 case EM_AMDGPU: return "AMD GPU";
3399 /* 230 (all reserved) */
3400 /* 240 */
3401 case EM_RISCV: return "RISC-V";
3402 case EM_LANAI: return "Lanai 32-bit processor";
3403 case EM_CEVA: return "CEVA Processor Architecture Family";
3404 case EM_CEVA_X2: return "CEVA X2 Processor Family";
3405 case EM_BPF: return "Linux BPF";
3406 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
3407 case EM_IMG1: return "Imagination Technologies";
3408 /* 250 */
3409 case EM_NFP: return "Netronome Flow Processor";
3410 case EM_VE: return "NEC Vector Engine";
3411 case EM_CSKY: return "C-SKY";
3412 case EM_ARC_COMPACT3_64: return "Synopsys ARCv3 64-bit processor";
3413 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
3414 case EM_ARC_COMPACT3: return "Synopsys ARCv3 32-bit processor";
3415 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
3416 case EM_65816: return "WDC 65816/65C816";
3417 case EM_LOONGARCH: return "LoongArch";
3418 case EM_KF32: return "ChipON KungFu32";
3420 /* Large numbers... */
3421 case EM_MT: return "Morpho Techologies MT processor";
3422 case EM_ALPHA: return "Alpha";
3423 case EM_WEBASSEMBLY: return "Web Assembly";
3424 case EM_DLX: return "OpenDLX";
3425 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3426 case EM_IQ2000: return "Vitesse IQ2000";
3427 case EM_M32C_OLD:
3428 case EM_NIOS32: return "Altera Nios";
3429 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
3430 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
3431 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
3432 case EM_S12Z: return "Freescale S12Z";
3434 default:
3435 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
3436 return buff;
3440 static char *
3441 decode_ARC_machine_flags (char *out, unsigned e_flags, unsigned e_machine)
3443 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
3444 other compilers don't specify an architecture type in the e_flags, and
3445 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
3446 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
3447 architectures.
3449 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
3450 but also sets a specific architecture type in the e_flags field.
3452 However, when decoding the flags we don't worry if we see an
3453 unexpected pairing, for example EM_ARC_COMPACT machine type, with
3454 ARCEM architecture type. */
3456 switch (e_flags & EF_ARC_MACH_MSK)
3458 /* We only expect these to occur for EM_ARC_COMPACT2. */
3459 case EF_ARC_CPU_ARCV2EM:
3460 out = stpcpy (out, ", ARC EM");
3461 break;
3462 case EF_ARC_CPU_ARCV2HS:
3463 out = stpcpy (out, ", ARC HS");
3464 break;
3466 /* We only expect these to occur for EM_ARC_COMPACT. */
3467 case E_ARC_MACH_ARC600:
3468 out = stpcpy (out, ", ARC600");
3469 break;
3470 case E_ARC_MACH_ARC601:
3471 out = stpcpy (out, ", ARC601");
3472 break;
3473 case E_ARC_MACH_ARC700:
3474 out = stpcpy (out, ", ARC700");
3475 break;
3477 /* The only times we should end up here are (a) A corrupt ELF, (b) A
3478 new ELF with new architecture being read by an old version of
3479 readelf, or (c) An ELF built with non-GNU compiler that does not
3480 set the architecture in the e_flags. */
3481 default:
3482 if (e_machine == EM_ARC_COMPACT)
3483 out = stpcpy (out, ", Unknown ARCompact");
3484 else
3485 out = stpcpy (out, ", Unknown ARC");
3486 break;
3489 switch (e_flags & EF_ARC_OSABI_MSK)
3491 case E_ARC_OSABI_ORIG:
3492 out = stpcpy (out, ", (ABI:legacy)");
3493 break;
3494 case E_ARC_OSABI_V2:
3495 out = stpcpy (out, ", (ABI:v2)");
3496 break;
3497 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3498 case E_ARC_OSABI_V3:
3499 out = stpcpy (out, ", v3 no-legacy-syscalls ABI");
3500 break;
3501 case E_ARC_OSABI_V4:
3502 out = stpcpy (out, ", v4 ABI");
3503 break;
3504 default:
3505 out = stpcpy (out, ", unrecognised ARC OSABI flag");
3506 break;
3508 return out;
3511 static char *
3512 decode_ARM_machine_flags (char *out, unsigned e_flags)
3514 unsigned eabi;
3515 bool unknown = false;
3517 eabi = EF_ARM_EABI_VERSION (e_flags);
3518 e_flags &= ~ EF_ARM_EABIMASK;
3520 /* Handle "generic" ARM flags. */
3521 if (e_flags & EF_ARM_RELEXEC)
3523 out = stpcpy (out, ", relocatable executable");
3524 e_flags &= ~ EF_ARM_RELEXEC;
3527 if (e_flags & EF_ARM_PIC)
3529 out = stpcpy (out, ", position independent");
3530 e_flags &= ~ EF_ARM_PIC;
3533 /* Now handle EABI specific flags. */
3534 switch (eabi)
3536 default:
3537 out = stpcpy (out, ", <unrecognized EABI>");
3538 if (e_flags)
3539 unknown = true;
3540 break;
3542 case EF_ARM_EABI_VER1:
3543 out = stpcpy (out, ", Version1 EABI");
3544 while (e_flags)
3546 unsigned flag;
3548 /* Process flags one bit at a time. */
3549 flag = e_flags & - e_flags;
3550 e_flags &= ~ flag;
3552 switch (flag)
3554 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
3555 out = stpcpy (out, ", sorted symbol tables");
3556 break;
3558 default:
3559 unknown = true;
3560 break;
3563 break;
3565 case EF_ARM_EABI_VER2:
3566 out = stpcpy (out, ", Version2 EABI");
3567 while (e_flags)
3569 unsigned flag;
3571 /* Process flags one bit at a time. */
3572 flag = e_flags & - e_flags;
3573 e_flags &= ~ flag;
3575 switch (flag)
3577 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
3578 out = stpcpy (out, ", sorted symbol tables");
3579 break;
3581 case EF_ARM_DYNSYMSUSESEGIDX:
3582 out = stpcpy (out, ", dynamic symbols use segment index");
3583 break;
3585 case EF_ARM_MAPSYMSFIRST:
3586 out = stpcpy (out, ", mapping symbols precede others");
3587 break;
3589 default:
3590 unknown = true;
3591 break;
3594 break;
3596 case EF_ARM_EABI_VER3:
3597 out = stpcpy (out, ", Version3 EABI");
3598 break;
3600 case EF_ARM_EABI_VER4:
3601 out = stpcpy (out, ", Version4 EABI");
3602 while (e_flags)
3604 unsigned flag;
3606 /* Process flags one bit at a time. */
3607 flag = e_flags & - e_flags;
3608 e_flags &= ~ flag;
3610 switch (flag)
3612 case EF_ARM_BE8:
3613 out = stpcpy (out, ", BE8");
3614 break;
3616 case EF_ARM_LE8:
3617 out = stpcpy (out, ", LE8");
3618 break;
3620 default:
3621 unknown = true;
3622 break;
3625 break;
3627 case EF_ARM_EABI_VER5:
3628 out = stpcpy (out, ", Version5 EABI");
3629 while (e_flags)
3631 unsigned flag;
3633 /* Process flags one bit at a time. */
3634 flag = e_flags & - e_flags;
3635 e_flags &= ~ flag;
3637 switch (flag)
3639 case EF_ARM_BE8:
3640 out = stpcpy (out, ", BE8");
3641 break;
3643 case EF_ARM_LE8:
3644 out = stpcpy (out, ", LE8");
3645 break;
3647 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
3648 out = stpcpy (out, ", soft-float ABI");
3649 break;
3651 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
3652 out = stpcpy (out, ", hard-float ABI");
3653 break;
3655 default:
3656 unknown = true;
3657 break;
3660 break;
3662 case EF_ARM_EABI_UNKNOWN:
3663 out = stpcpy (out, ", GNU EABI");
3664 while (e_flags)
3666 unsigned flag;
3668 /* Process flags one bit at a time. */
3669 flag = e_flags & - e_flags;
3670 e_flags &= ~ flag;
3672 switch (flag)
3674 case EF_ARM_INTERWORK:
3675 out = stpcpy (out, ", interworking enabled");
3676 break;
3678 case EF_ARM_APCS_26:
3679 out = stpcpy (out, ", uses APCS/26");
3680 break;
3682 case EF_ARM_APCS_FLOAT:
3683 out = stpcpy (out, ", uses APCS/float");
3684 break;
3686 case EF_ARM_PIC:
3687 out = stpcpy (out, ", position independent");
3688 break;
3690 case EF_ARM_ALIGN8:
3691 out = stpcpy (out, ", 8 bit structure alignment");
3692 break;
3694 case EF_ARM_NEW_ABI:
3695 out = stpcpy (out, ", uses new ABI");
3696 break;
3698 case EF_ARM_OLD_ABI:
3699 out = stpcpy (out, ", uses old ABI");
3700 break;
3702 case EF_ARM_SOFT_FLOAT:
3703 out = stpcpy (out, ", software FP");
3704 break;
3706 case EF_ARM_VFP_FLOAT:
3707 out = stpcpy (out, ", VFP");
3708 break;
3710 default:
3711 unknown = true;
3712 break;
3717 if (unknown)
3718 out = stpcpy (out,_(", <unknown>"));
3719 return out;
3722 static char *
3723 decode_AVR_machine_flags (char *out, unsigned e_flags)
3725 switch (e_flags & EF_AVR_MACH)
3727 case E_AVR_MACH_AVR1:
3728 out = stpcpy (out, ", avr:1");
3729 break;
3730 case E_AVR_MACH_AVR2:
3731 out = stpcpy (out, ", avr:2");
3732 break;
3733 case E_AVR_MACH_AVR25:
3734 out = stpcpy (out, ", avr:25");
3735 break;
3736 case E_AVR_MACH_AVR3:
3737 out = stpcpy (out, ", avr:3");
3738 break;
3739 case E_AVR_MACH_AVR31:
3740 out = stpcpy (out, ", avr:31");
3741 break;
3742 case E_AVR_MACH_AVR35:
3743 out = stpcpy (out, ", avr:35");
3744 break;
3745 case E_AVR_MACH_AVR4:
3746 out = stpcpy (out, ", avr:4");
3747 break;
3748 case E_AVR_MACH_AVR5:
3749 out = stpcpy (out, ", avr:5");
3750 break;
3751 case E_AVR_MACH_AVR51:
3752 out = stpcpy (out, ", avr:51");
3753 break;
3754 case E_AVR_MACH_AVR6:
3755 out = stpcpy (out, ", avr:6");
3756 break;
3757 case E_AVR_MACH_AVRTINY:
3758 out = stpcpy (out, ", avr:100");
3759 break;
3760 case E_AVR_MACH_XMEGA1:
3761 out = stpcpy (out, ", avr:101");
3762 break;
3763 case E_AVR_MACH_XMEGA2:
3764 out = stpcpy (out, ", avr:102");
3765 break;
3766 case E_AVR_MACH_XMEGA3:
3767 out = stpcpy (out, ", avr:103");
3768 break;
3769 case E_AVR_MACH_XMEGA4:
3770 out = stpcpy (out, ", avr:104");
3771 break;
3772 case E_AVR_MACH_XMEGA5:
3773 out = stpcpy (out, ", avr:105");
3774 break;
3775 case E_AVR_MACH_XMEGA6:
3776 out = stpcpy (out, ", avr:106");
3777 break;
3778 case E_AVR_MACH_XMEGA7:
3779 out = stpcpy (out, ", avr:107");
3780 break;
3781 default:
3782 out = stpcpy (out, ", avr:<unknown>");
3783 break;
3786 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
3787 out = stpcpy (out, ", link-relax");
3788 return out;
3791 static char *
3792 decode_BLACKFIN_machine_flags (char *out, unsigned e_flags)
3794 if (e_flags & EF_BFIN_PIC)
3795 out = stpcpy (out, ", PIC");
3797 if (e_flags & EF_BFIN_FDPIC)
3798 out = stpcpy (out, ", FDPIC");
3800 if (e_flags & EF_BFIN_CODE_IN_L1)
3801 out = stpcpy (out, ", code in L1");
3803 if (e_flags & EF_BFIN_DATA_IN_L1)
3804 out = stpcpy (out, ", data in L1");
3805 return out;
3808 static char *
3809 decode_FRV_machine_flags (char *out, unsigned e_flags)
3811 switch (e_flags & EF_FRV_CPU_MASK)
3813 case EF_FRV_CPU_GENERIC:
3814 break;
3816 default:
3817 out = stpcpy (out, ", fr???");
3818 break;
3820 case EF_FRV_CPU_FR300:
3821 out = stpcpy (out, ", fr300");
3822 break;
3824 case EF_FRV_CPU_FR400:
3825 out = stpcpy (out, ", fr400");
3826 break;
3827 case EF_FRV_CPU_FR405:
3828 out = stpcpy (out, ", fr405");
3829 break;
3831 case EF_FRV_CPU_FR450:
3832 out = stpcpy (out, ", fr450");
3833 break;
3835 case EF_FRV_CPU_FR500:
3836 out = stpcpy (out, ", fr500");
3837 break;
3838 case EF_FRV_CPU_FR550:
3839 out = stpcpy (out, ", fr550");
3840 break;
3842 case EF_FRV_CPU_SIMPLE:
3843 out = stpcpy (out, ", simple");
3844 break;
3845 case EF_FRV_CPU_TOMCAT:
3846 out = stpcpy (out, ", tomcat");
3847 break;
3849 return out;
3852 static char *
3853 decode_IA64_machine_flags (char *out, unsigned e_flags, Filedata *filedata)
3855 if ((e_flags & EF_IA_64_ABI64))
3856 out = stpcpy (out, ", 64-bit");
3857 else
3858 out = stpcpy (out, ", 32-bit");
3859 if ((e_flags & EF_IA_64_REDUCEDFP))
3860 out = stpcpy (out, ", reduced fp model");
3861 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3862 out = stpcpy (out, ", no function descriptors, constant gp");
3863 else if ((e_flags & EF_IA_64_CONS_GP))
3864 out = stpcpy (out, ", constant gp");
3865 if ((e_flags & EF_IA_64_ABSOLUTE))
3866 out = stpcpy (out, ", absolute");
3867 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
3869 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3870 out = stpcpy (out, ", vms_linkages");
3871 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3873 case EF_IA_64_VMS_COMCOD_SUCCESS:
3874 break;
3875 case EF_IA_64_VMS_COMCOD_WARNING:
3876 out = stpcpy (out, ", warning");
3877 break;
3878 case EF_IA_64_VMS_COMCOD_ERROR:
3879 out = stpcpy (out, ", error");
3880 break;
3881 case EF_IA_64_VMS_COMCOD_ABORT:
3882 out = stpcpy (out, ", abort");
3883 break;
3884 default:
3885 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3886 e_flags & EF_IA_64_VMS_COMCOD);
3887 out = stpcpy (out, ", <unknown>");
3890 return out;
3893 static char *
3894 decode_LOONGARCH_machine_flags (char *out, unsigned int e_flags)
3896 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
3897 out = stpcpy (out, ", SOFT-FLOAT");
3898 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
3899 out = stpcpy (out, ", SINGLE-FLOAT");
3900 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
3901 out = stpcpy (out, ", DOUBLE-FLOAT");
3903 if (EF_LOONGARCH_IS_OBJ_V0 (e_flags))
3904 out = stpcpy (out, ", OBJ-v0");
3905 else if (EF_LOONGARCH_IS_OBJ_V1 (e_flags))
3906 out = stpcpy (out, ", OBJ-v1");
3907 return out;
3910 static char *
3911 decode_M68K_machine_flags (char *out, unsigned int e_flags)
3913 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
3914 out = stpcpy (out, ", m68000");
3915 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3916 out = stpcpy (out, ", cpu32");
3917 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3918 out = stpcpy (out, ", fido_a");
3919 else
3921 char const *isa = _("unknown");
3922 char const *mac = _("unknown mac");
3923 char const *additional = NULL;
3925 switch (e_flags & EF_M68K_CF_ISA_MASK)
3927 case EF_M68K_CF_ISA_A_NODIV:
3928 isa = "A";
3929 additional = ", nodiv";
3930 break;
3931 case EF_M68K_CF_ISA_A:
3932 isa = "A";
3933 break;
3934 case EF_M68K_CF_ISA_A_PLUS:
3935 isa = "A+";
3936 break;
3937 case EF_M68K_CF_ISA_B_NOUSP:
3938 isa = "B";
3939 additional = ", nousp";
3940 break;
3941 case EF_M68K_CF_ISA_B:
3942 isa = "B";
3943 break;
3944 case EF_M68K_CF_ISA_C:
3945 isa = "C";
3946 break;
3947 case EF_M68K_CF_ISA_C_NODIV:
3948 isa = "C";
3949 additional = ", nodiv";
3950 break;
3952 out = stpcpy (out, ", cf, isa ");
3953 out = stpcpy (out, isa);
3954 if (additional)
3955 out = stpcpy (out, additional);
3956 if (e_flags & EF_M68K_CF_FLOAT)
3957 out = stpcpy (out, ", float");
3958 switch (e_flags & EF_M68K_CF_MAC_MASK)
3960 case 0:
3961 mac = NULL;
3962 break;
3963 case EF_M68K_CF_MAC:
3964 mac = "mac";
3965 break;
3966 case EF_M68K_CF_EMAC:
3967 mac = "emac";
3968 break;
3969 case EF_M68K_CF_EMAC_B:
3970 mac = "emac_b";
3971 break;
3973 if (mac)
3975 out = stpcpy (out, ", ");
3976 out = stpcpy (out, mac);
3979 return out;
3982 static char *
3983 decode_MeP_machine_flags (char *out, unsigned int e_flags)
3985 switch (e_flags & EF_MEP_CPU_MASK)
3987 case EF_MEP_CPU_MEP:
3988 out = stpcpy (out, ", generic MeP");
3989 break;
3990 case EF_MEP_CPU_C2:
3991 out = stpcpy (out, ", MeP C2");
3992 break;
3993 case EF_MEP_CPU_C3:
3994 out = stpcpy (out, ", MeP C3");
3995 break;
3996 case EF_MEP_CPU_C4:
3997 out = stpcpy (out, ", MeP C4");
3998 break;
3999 case EF_MEP_CPU_C5:
4000 out = stpcpy (out, ", MeP C5");
4001 break;
4002 case EF_MEP_CPU_H1:
4003 out = stpcpy (out, ", MeP H1");
4004 break;
4005 default:
4006 out = stpcpy (out, _(", <unknown MeP cpu type>"));
4007 break;
4010 switch (e_flags & EF_MEP_COP_MASK)
4012 case EF_MEP_COP_NONE:
4013 break;
4014 case EF_MEP_COP_AVC:
4015 out = stpcpy (out, ", AVC coprocessor");
4016 break;
4017 case EF_MEP_COP_AVC2:
4018 out = stpcpy (out, ", AVC2 coprocessor");
4019 break;
4020 case EF_MEP_COP_FMAX:
4021 out = stpcpy (out, ", FMAX coprocessor");
4022 break;
4023 case EF_MEP_COP_IVC2:
4024 out = stpcpy (out, ", IVC2 coprocessor");
4025 break;
4026 default:
4027 out = stpcpy (out, _("<unknown MeP copro type>"));
4028 break;
4031 if (e_flags & EF_MEP_LIBRARY)
4032 out = stpcpy (out, ", Built for Library");
4034 if (e_flags & EF_MEP_INDEX_MASK)
4035 out += sprintf (out, ", Configuration Index: %#x",
4036 e_flags & EF_MEP_INDEX_MASK);
4038 if (e_flags & ~ EF_MEP_ALL_FLAGS)
4039 out += sprintf (out, _(", unknown flags bits: %#x"),
4040 e_flags & ~ EF_MEP_ALL_FLAGS);
4041 return out;
4044 static char *
4045 decode_MIPS_machine_flags (char *out, unsigned int e_flags)
4047 if (e_flags & EF_MIPS_NOREORDER)
4048 out = stpcpy (out, ", noreorder");
4050 if (e_flags & EF_MIPS_PIC)
4051 out = stpcpy (out, ", pic");
4053 if (e_flags & EF_MIPS_CPIC)
4054 out = stpcpy (out, ", cpic");
4056 if (e_flags & EF_MIPS_UCODE)
4057 out = stpcpy (out, ", ugen_reserved");
4059 if (e_flags & EF_MIPS_ABI2)
4060 out = stpcpy (out, ", abi2");
4062 if (e_flags & EF_MIPS_OPTIONS_FIRST)
4063 out = stpcpy (out, ", odk first");
4065 if (e_flags & EF_MIPS_32BITMODE)
4066 out = stpcpy (out, ", 32bitmode");
4068 if (e_flags & EF_MIPS_NAN2008)
4069 out = stpcpy (out, ", nan2008");
4071 if (e_flags & EF_MIPS_FP64)
4072 out = stpcpy (out, ", fp64");
4074 switch ((e_flags & EF_MIPS_MACH))
4076 case EF_MIPS_MACH_3900:
4077 out = stpcpy (out, ", 3900");
4078 break;
4079 case EF_MIPS_MACH_4010:
4080 out = stpcpy (out, ", 4010");
4081 break;
4082 case EF_MIPS_MACH_4100:
4083 out = stpcpy (out, ", 4100");
4084 break;
4085 case EF_MIPS_MACH_4111:
4086 out = stpcpy (out, ", 4111");
4087 break;
4088 case EF_MIPS_MACH_4120:
4089 out = stpcpy (out, ", 4120");
4090 break;
4091 case EF_MIPS_MACH_4650:
4092 out = stpcpy (out, ", 4650");
4093 break;
4094 case EF_MIPS_MACH_5400:
4095 out = stpcpy (out, ", 5400");
4096 break;
4097 case EF_MIPS_MACH_5500:
4098 out = stpcpy (out, ", 5500");
4099 break;
4100 case EF_MIPS_MACH_5900:
4101 out = stpcpy (out, ", 5900");
4102 break;
4103 case EF_MIPS_MACH_SB1:
4104 out = stpcpy (out, ", sb1");
4105 break;
4106 case EF_MIPS_MACH_9000:
4107 out = stpcpy (out, ", 9000");
4108 break;
4109 case EF_MIPS_MACH_LS2E:
4110 out = stpcpy (out, ", loongson-2e");
4111 break;
4112 case EF_MIPS_MACH_LS2F:
4113 out = stpcpy (out, ", loongson-2f");
4114 break;
4115 case EF_MIPS_MACH_GS464:
4116 out = stpcpy (out, ", gs464");
4117 break;
4118 case EF_MIPS_MACH_GS464E:
4119 out = stpcpy (out, ", gs464e");
4120 break;
4121 case EF_MIPS_MACH_GS264E:
4122 out = stpcpy (out, ", gs264e");
4123 break;
4124 case EF_MIPS_MACH_OCTEON:
4125 out = stpcpy (out, ", octeon");
4126 break;
4127 case EF_MIPS_MACH_OCTEON2:
4128 out = stpcpy (out, ", octeon2");
4129 break;
4130 case EF_MIPS_MACH_OCTEON3:
4131 out = stpcpy (out, ", octeon3");
4132 break;
4133 case EF_MIPS_MACH_XLR:
4134 out = stpcpy (out, ", xlr");
4135 break;
4136 case EF_MIPS_MACH_IAMR2:
4137 out = stpcpy (out, ", interaptiv-mr2");
4138 break;
4139 case EF_MIPS_MACH_ALLEGREX:
4140 out = stpcpy (out, ", allegrex");
4141 break;
4142 case 0:
4143 /* We simply ignore the field in this case to avoid confusion:
4144 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
4145 extension. */
4146 break;
4147 default:
4148 out = stpcpy (out, _(", unknown CPU"));
4149 break;
4152 switch ((e_flags & EF_MIPS_ABI))
4154 case EF_MIPS_ABI_O32:
4155 out = stpcpy (out, ", o32");
4156 break;
4157 case EF_MIPS_ABI_O64:
4158 out = stpcpy (out, ", o64");
4159 break;
4160 case EF_MIPS_ABI_EABI32:
4161 out = stpcpy (out, ", eabi32");
4162 break;
4163 case EF_MIPS_ABI_EABI64:
4164 out = stpcpy (out, ", eabi64");
4165 break;
4166 case 0:
4167 /* We simply ignore the field in this case to avoid confusion:
4168 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
4169 This means it is likely to be an o32 file, but not for
4170 sure. */
4171 break;
4172 default:
4173 out = stpcpy (out, _(", unknown ABI"));
4174 break;
4177 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
4178 out = stpcpy (out, ", mdmx");
4180 if (e_flags & EF_MIPS_ARCH_ASE_M16)
4181 out = stpcpy (out, ", mips16");
4183 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
4184 out = stpcpy (out, ", micromips");
4186 switch ((e_flags & EF_MIPS_ARCH))
4188 case EF_MIPS_ARCH_1:
4189 out = stpcpy (out, ", mips1");
4190 break;
4191 case EF_MIPS_ARCH_2:
4192 out = stpcpy (out, ", mips2");
4193 break;
4194 case EF_MIPS_ARCH_3:
4195 out = stpcpy (out, ", mips3");
4196 break;
4197 case EF_MIPS_ARCH_4:
4198 out = stpcpy (out, ", mips4");
4199 break;
4200 case EF_MIPS_ARCH_5:
4201 out = stpcpy (out, ", mips5");
4202 break;
4203 case EF_MIPS_ARCH_32:
4204 out = stpcpy (out, ", mips32");
4205 break;
4206 case EF_MIPS_ARCH_32R2:
4207 out = stpcpy (out, ", mips32r2");
4208 break;
4209 case EF_MIPS_ARCH_32R6:
4210 out = stpcpy (out, ", mips32r6");
4211 break;
4212 case EF_MIPS_ARCH_64:
4213 out = stpcpy (out, ", mips64");
4214 break;
4215 case EF_MIPS_ARCH_64R2:
4216 out = stpcpy (out, ", mips64r2");
4217 break;
4218 case EF_MIPS_ARCH_64R6:
4219 out = stpcpy (out, ", mips64r6");
4220 break;
4221 default:
4222 out = stpcpy (out, _(", unknown ISA"));
4223 break;
4225 return out;
4228 static char *
4229 decode_MSP430_machine_flags (char *out, unsigned e_flags)
4231 out = stpcpy (out, _(": architecture variant: "));
4232 switch (e_flags & EF_MSP430_MACH)
4234 case E_MSP430_MACH_MSP430x11:
4235 out = stpcpy (out, "MSP430x11");
4236 break;
4237 case E_MSP430_MACH_MSP430x11x1:
4238 out = stpcpy (out, "MSP430x11x1 ");
4239 break;
4240 case E_MSP430_MACH_MSP430x12:
4241 out = stpcpy (out, "MSP430x12");
4242 break;
4243 case E_MSP430_MACH_MSP430x13:
4244 out = stpcpy (out, "MSP430x13");
4245 break;
4246 case E_MSP430_MACH_MSP430x14:
4247 out = stpcpy (out, "MSP430x14");
4248 break;
4249 case E_MSP430_MACH_MSP430x15:
4250 out = stpcpy (out, "MSP430x15");
4251 break;
4252 case E_MSP430_MACH_MSP430x16:
4253 out = stpcpy (out, "MSP430x16");
4254 break;
4255 case E_MSP430_MACH_MSP430x31:
4256 out = stpcpy (out, "MSP430x31");
4257 break;
4258 case E_MSP430_MACH_MSP430x32:
4259 out = stpcpy (out, "MSP430x32");
4260 break;
4261 case E_MSP430_MACH_MSP430x33:
4262 out = stpcpy (out, "MSP430x33");
4263 break;
4264 case E_MSP430_MACH_MSP430x41:
4265 out = stpcpy (out, "MSP430x41");
4266 break;
4267 case E_MSP430_MACH_MSP430x42:
4268 out = stpcpy (out, "MSP430x42");
4269 break;
4270 case E_MSP430_MACH_MSP430x43:
4271 out = stpcpy (out, "MSP430x43");
4272 break;
4273 case E_MSP430_MACH_MSP430x44:
4274 out = stpcpy (out, "MSP430x44");
4275 break;
4276 case E_MSP430_MACH_MSP430X :
4277 out = stpcpy (out, "MSP430X");
4278 break;
4279 default:
4280 out = stpcpy (out, _(": unknown"));
4281 break;
4284 if (e_flags & ~ EF_MSP430_MACH)
4285 out = stpcpy (out, _(": unknown extra flag bits also present"));
4286 return out;
4289 static char *
4290 decode_NDS32_machine_flags (char *out, unsigned e_flags)
4292 unsigned abi;
4293 unsigned arch;
4294 unsigned config;
4295 unsigned version;
4296 bool has_fpu = false;
4298 static const char *ABI_STRINGS[] =
4300 "ABI v0", /* use r5 as return register; only used in N1213HC */
4301 "ABI v1", /* use r0 as return register */
4302 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
4303 "ABI v2fp", /* for FPU */
4304 "AABI",
4305 "ABI2 FP+"
4307 static const char *VER_STRINGS[] =
4309 "Andes ELF V1.3 or older",
4310 "Andes ELF V1.3.1",
4311 "Andes ELF V1.4"
4313 static const char *ARCH_STRINGS[] =
4316 "Andes Star v1.0",
4317 "Andes Star v2.0",
4318 "Andes Star v3.0",
4319 "Andes Star v3.0m"
4322 abi = EF_NDS_ABI & e_flags;
4323 arch = EF_NDS_ARCH & e_flags;
4324 config = EF_NDS_INST & e_flags;
4325 version = EF_NDS32_ELF_VERSION & e_flags;
4327 switch (abi)
4329 case E_NDS_ABI_V0:
4330 case E_NDS_ABI_V1:
4331 case E_NDS_ABI_V2:
4332 case E_NDS_ABI_V2FP:
4333 case E_NDS_ABI_AABI:
4334 case E_NDS_ABI_V2FP_PLUS:
4335 /* In case there are holes in the array. */
4336 out += sprintf (out, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
4337 break;
4339 default:
4340 out = stpcpy (out, ", <unrecognized ABI>");
4341 break;
4344 switch (version)
4346 case E_NDS32_ELF_VER_1_2:
4347 case E_NDS32_ELF_VER_1_3:
4348 case E_NDS32_ELF_VER_1_4:
4349 out += sprintf (out, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
4350 break;
4352 default:
4353 out = stpcpy (out, ", <unrecognized ELF version number>");
4354 break;
4357 if (E_NDS_ABI_V0 == abi)
4359 /* OLD ABI; only used in N1213HC, has performance extension 1. */
4360 out = stpcpy (out, ", Andes Star v1.0, N1213HC, MAC, PERF1");
4361 if (arch == E_NDS_ARCH_STAR_V1_0)
4362 out = stpcpy (out, ", 16b"); /* has 16-bit instructions */
4363 return out;
4366 switch (arch)
4368 case E_NDS_ARCH_STAR_V1_0:
4369 case E_NDS_ARCH_STAR_V2_0:
4370 case E_NDS_ARCH_STAR_V3_0:
4371 case E_NDS_ARCH_STAR_V3_M:
4372 out += sprintf (out, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
4373 break;
4375 default:
4376 out = stpcpy (out, ", <unrecognized architecture>");
4377 /* ARCH version determines how the e_flags are interpreted.
4378 If it is unknown, we cannot proceed. */
4379 return out;
4382 /* Newer ABI; Now handle architecture specific flags. */
4383 if (arch == E_NDS_ARCH_STAR_V1_0)
4385 if (config & E_NDS32_HAS_MFUSR_PC_INST)
4386 out = stpcpy (out, ", MFUSR_PC");
4388 if (!(config & E_NDS32_HAS_NO_MAC_INST))
4389 out = stpcpy (out, ", MAC");
4391 if (config & E_NDS32_HAS_DIV_INST)
4392 out = stpcpy (out, ", DIV");
4394 if (config & E_NDS32_HAS_16BIT_INST)
4395 out = stpcpy (out, ", 16b");
4397 else
4399 if (config & E_NDS32_HAS_MFUSR_PC_INST)
4401 if (version <= E_NDS32_ELF_VER_1_3)
4402 out = stpcpy (out, ", [B8]");
4403 else
4404 out = stpcpy (out, ", EX9");
4407 if (config & E_NDS32_HAS_MAC_DX_INST)
4408 out = stpcpy (out, ", MAC_DX");
4410 if (config & E_NDS32_HAS_DIV_DX_INST)
4411 out = stpcpy (out, ", DIV_DX");
4413 if (config & E_NDS32_HAS_16BIT_INST)
4415 if (version <= E_NDS32_ELF_VER_1_3)
4416 out = stpcpy (out, ", 16b");
4417 else
4418 out = stpcpy (out, ", IFC");
4422 if (config & E_NDS32_HAS_EXT_INST)
4423 out = stpcpy (out, ", PERF1");
4425 if (config & E_NDS32_HAS_EXT2_INST)
4426 out = stpcpy (out, ", PERF2");
4428 if (config & E_NDS32_HAS_FPU_INST)
4430 has_fpu = true;
4431 out = stpcpy (out, ", FPU_SP");
4434 if (config & E_NDS32_HAS_FPU_DP_INST)
4436 has_fpu = true;
4437 out = stpcpy (out, ", FPU_DP");
4440 if (config & E_NDS32_HAS_FPU_MAC_INST)
4442 has_fpu = true;
4443 out = stpcpy (out, ", FPU_MAC");
4446 if (has_fpu)
4448 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
4450 case E_NDS32_FPU_REG_8SP_4DP:
4451 out = stpcpy (out, ", FPU_REG:8/4");
4452 break;
4453 case E_NDS32_FPU_REG_16SP_8DP:
4454 out = stpcpy (out, ", FPU_REG:16/8");
4455 break;
4456 case E_NDS32_FPU_REG_32SP_16DP:
4457 out = stpcpy (out, ", FPU_REG:32/16");
4458 break;
4459 case E_NDS32_FPU_REG_32SP_32DP:
4460 out = stpcpy (out, ", FPU_REG:32/32");
4461 break;
4465 if (config & E_NDS32_HAS_AUDIO_INST)
4466 out = stpcpy (out, ", AUDIO");
4468 if (config & E_NDS32_HAS_STRING_INST)
4469 out = stpcpy (out, ", STR");
4471 if (config & E_NDS32_HAS_REDUCED_REGS)
4472 out = stpcpy (out, ", 16REG");
4474 if (config & E_NDS32_HAS_VIDEO_INST)
4476 if (version <= E_NDS32_ELF_VER_1_3)
4477 out = stpcpy (out, ", VIDEO");
4478 else
4479 out = stpcpy (out, ", SATURATION");
4482 if (config & E_NDS32_HAS_ENCRIPT_INST)
4483 out = stpcpy (out, ", ENCRP");
4485 if (config & E_NDS32_HAS_L2C_INST)
4486 out = stpcpy (out, ", L2C");
4488 return out;
4491 static char *
4492 decode_PARISC_machine_flags (char *out, unsigned e_flags)
4494 switch (e_flags & EF_PARISC_ARCH)
4496 case EFA_PARISC_1_0:
4497 out = stpcpy (out, ", PA-RISC 1.0");
4498 break;
4499 case EFA_PARISC_1_1:
4500 out = stpcpy (out, ", PA-RISC 1.1");
4501 break;
4502 case EFA_PARISC_2_0:
4503 out = stpcpy (out, ", PA-RISC 2.0");
4504 break;
4505 default:
4506 break;
4508 if (e_flags & EF_PARISC_TRAPNIL)
4509 out = stpcpy (out, ", trapnil");
4510 if (e_flags & EF_PARISC_EXT)
4511 out = stpcpy (out, ", ext");
4512 if (e_flags & EF_PARISC_LSB)
4513 out = stpcpy (out, ", lsb");
4514 if (e_flags & EF_PARISC_WIDE)
4515 out = stpcpy (out, ", wide");
4516 if (e_flags & EF_PARISC_NO_KABP)
4517 out = stpcpy (out, ", no kabp");
4518 if (e_flags & EF_PARISC_LAZYSWAP)
4519 out = stpcpy (out, ", lazyswap");
4520 return out;
4523 static char *
4524 decode_RISCV_machine_flags (char *out, unsigned e_flags)
4526 if (e_flags & EF_RISCV_RVC)
4527 out = stpcpy (out, ", RVC");
4529 if (e_flags & EF_RISCV_RVE)
4530 out = stpcpy (out, ", RVE");
4532 if (e_flags & EF_RISCV_TSO)
4533 out = stpcpy (out, ", TSO");
4535 switch (e_flags & EF_RISCV_FLOAT_ABI)
4537 case EF_RISCV_FLOAT_ABI_SOFT:
4538 out = stpcpy (out, ", soft-float ABI");
4539 break;
4541 case EF_RISCV_FLOAT_ABI_SINGLE:
4542 out = stpcpy (out, ", single-float ABI");
4543 break;
4545 case EF_RISCV_FLOAT_ABI_DOUBLE:
4546 out = stpcpy (out, ", double-float ABI");
4547 break;
4549 case EF_RISCV_FLOAT_ABI_QUAD:
4550 out = stpcpy (out, ", quad-float ABI");
4551 break;
4553 return out;
4556 static char *
4557 decode_RL78_machine_flags (char *out, unsigned e_flags)
4559 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4561 case E_FLAG_RL78_ANY_CPU:
4562 break;
4563 case E_FLAG_RL78_G10:
4564 out = stpcpy (out, ", G10");
4565 break;
4566 case E_FLAG_RL78_G13:
4567 out = stpcpy (out, ", G13");
4568 break;
4569 case E_FLAG_RL78_G14:
4570 out = stpcpy (out, ", G14");
4571 break;
4573 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4574 out = stpcpy (out, ", 64-bit doubles");
4575 return out;
4578 static char *
4579 decode_RX_machine_flags (char *out, unsigned e_flags)
4581 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4582 out = stpcpy (out, ", 64-bit doubles");
4583 if (e_flags & E_FLAG_RX_DSP)
4584 out = stpcpy (out, ", dsp");
4585 if (e_flags & E_FLAG_RX_PID)
4586 out = stpcpy (out, ", pid");
4587 if (e_flags & E_FLAG_RX_ABI)
4588 out = stpcpy (out, ", RX ABI");
4589 if (e_flags & E_FLAG_RX_SINSNS_SET)
4590 out = stpcpy (out, (e_flags & E_FLAG_RX_SINSNS_YES
4591 ? ", uses String instructions"
4592 : ", bans String instructions"));
4593 if (e_flags & E_FLAG_RX_V2)
4594 out = stpcpy (out, ", V2");
4595 if (e_flags & E_FLAG_RX_V3)
4596 out = stpcpy (out, ", V3");
4597 return out;
4600 static char *
4601 decode_SH_machine_flags (char *out, unsigned e_flags)
4603 switch ((e_flags & EF_SH_MACH_MASK))
4605 case EF_SH1:
4606 out = stpcpy (out, ", sh1");
4607 break;
4608 case EF_SH2:
4609 out = stpcpy (out, ", sh2");
4610 break;
4611 case EF_SH3:
4612 out = stpcpy (out, ", sh3");
4613 break;
4614 case EF_SH_DSP:
4615 out = stpcpy (out, ", sh-dsp");
4616 break;
4617 case EF_SH3_DSP:
4618 out = stpcpy (out, ", sh3-dsp");
4619 break;
4620 case EF_SH4AL_DSP:
4621 out = stpcpy (out, ", sh4al-dsp");
4622 break;
4623 case EF_SH3E:
4624 out = stpcpy (out, ", sh3e");
4625 break;
4626 case EF_SH4:
4627 out = stpcpy (out, ", sh4");
4628 break;
4629 case EF_SH5:
4630 out = stpcpy (out, ", sh5");
4631 break;
4632 case EF_SH2E:
4633 out = stpcpy (out, ", sh2e");
4634 break;
4635 case EF_SH4A:
4636 out = stpcpy (out, ", sh4a");
4637 break;
4638 case EF_SH2A:
4639 out = stpcpy (out, ", sh2a");
4640 break;
4641 case EF_SH4_NOFPU:
4642 out = stpcpy (out, ", sh4-nofpu");
4643 break;
4644 case EF_SH4A_NOFPU:
4645 out = stpcpy (out, ", sh4a-nofpu");
4646 break;
4647 case EF_SH2A_NOFPU:
4648 out = stpcpy (out, ", sh2a-nofpu");
4649 break;
4650 case EF_SH3_NOMMU:
4651 out = stpcpy (out, ", sh3-nommu");
4652 break;
4653 case EF_SH4_NOMMU_NOFPU:
4654 out = stpcpy (out, ", sh4-nommu-nofpu");
4655 break;
4656 case EF_SH2A_SH4_NOFPU:
4657 out = stpcpy (out, ", sh2a-nofpu-or-sh4-nommu-nofpu");
4658 break;
4659 case EF_SH2A_SH3_NOFPU:
4660 out = stpcpy (out, ", sh2a-nofpu-or-sh3-nommu");
4661 break;
4662 case EF_SH2A_SH4:
4663 out = stpcpy (out, ", sh2a-or-sh4");
4664 break;
4665 case EF_SH2A_SH3E:
4666 out = stpcpy (out, ", sh2a-or-sh3e");
4667 break;
4668 default:
4669 out = stpcpy (out, _(", unknown ISA"));
4670 break;
4673 if (e_flags & EF_SH_PIC)
4674 out = stpcpy (out, ", pic");
4676 if (e_flags & EF_SH_FDPIC)
4677 out = stpcpy (out, ", fdpic");
4678 return out;
4681 static char *
4682 decode_SPARC_machine_flags (char *out, unsigned e_flags)
4684 if (e_flags & EF_SPARC_32PLUS)
4685 out = stpcpy (out, ", v8+");
4687 if (e_flags & EF_SPARC_SUN_US1)
4688 out = stpcpy (out, ", ultrasparcI");
4690 if (e_flags & EF_SPARC_SUN_US3)
4691 out = stpcpy (out, ", ultrasparcIII");
4693 if (e_flags & EF_SPARC_HAL_R1)
4694 out = stpcpy (out, ", halr1");
4696 if (e_flags & EF_SPARC_LEDATA)
4697 out = stpcpy (out, ", ledata");
4699 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4700 out = stpcpy (out, ", tso");
4702 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4703 out = stpcpy (out, ", pso");
4705 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4706 out = stpcpy (out, ", rmo");
4707 return out;
4710 static char *
4711 decode_V800_machine_flags (char *out, unsigned int e_flags)
4713 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
4714 out = stpcpy (out, ", RH850 ABI");
4716 if (e_flags & EF_V800_850E3)
4717 out = stpcpy (out, ", V3 architecture");
4719 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
4720 out = stpcpy (out, ", FPU not used");
4722 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
4723 out = stpcpy (out, ", regmode: COMMON");
4725 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
4726 out = stpcpy (out, ", r4 not used");
4728 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
4729 out = stpcpy (out, ", r30 not used");
4731 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
4732 out = stpcpy (out, ", r5 not used");
4734 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
4735 out = stpcpy (out, ", r2 not used");
4737 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
4739 switch (e_flags & - e_flags)
4741 case EF_RH850_FPU_DOUBLE:
4742 out = stpcpy (out, ", double precision FPU");
4743 break;
4744 case EF_RH850_FPU_SINGLE:
4745 out = stpcpy (out, ", single precision FPU");
4746 break;
4747 case EF_RH850_REGMODE22:
4748 out = stpcpy (out, ", regmode:22");
4749 break;
4750 case EF_RH850_REGMODE32:
4751 out = stpcpy (out, ", regmode:23");
4752 break;
4753 case EF_RH850_GP_FIX:
4754 out = stpcpy (out, ", r4 fixed");
4755 break;
4756 case EF_RH850_GP_NOFIX:
4757 out = stpcpy (out, ", r4 free");
4758 break;
4759 case EF_RH850_EP_FIX:
4760 out = stpcpy (out, ", r30 fixed");
4761 break;
4762 case EF_RH850_EP_NOFIX:
4763 out = stpcpy (out, ", r30 free");
4764 break;
4765 case EF_RH850_TP_FIX:
4766 out = stpcpy (out, ", r5 fixed");
4767 break;
4768 case EF_RH850_TP_NOFIX:
4769 out = stpcpy (out, ", r5 free");
4770 break;
4771 case EF_RH850_REG2_RESERVE:
4772 out = stpcpy (out, ", r2 fixed");
4773 break;
4774 case EF_RH850_REG2_NORESERVE:
4775 out = stpcpy (out, ", r2 free");
4776 break;
4777 default:
4778 break;
4781 return out;
4784 static char *
4785 decode_V850_machine_flags (char *out, unsigned int e_flags)
4787 switch (e_flags & EF_V850_ARCH)
4789 case E_V850E3V5_ARCH:
4790 out = stpcpy (out, ", v850e3v5");
4791 break;
4792 case E_V850E2V3_ARCH:
4793 out = stpcpy (out, ", v850e2v3");
4794 break;
4795 case E_V850E2_ARCH:
4796 out = stpcpy (out, ", v850e2");
4797 break;
4798 case E_V850E1_ARCH:
4799 out = stpcpy (out, ", v850e1");
4800 break;
4801 case E_V850E_ARCH:
4802 out = stpcpy (out, ", v850e");
4803 break;
4804 case E_V850_ARCH:
4805 out = stpcpy (out, ", v850");
4806 break;
4807 default:
4808 out = stpcpy (out, _(", unknown v850 architecture variant"));
4809 break;
4811 return out;
4814 static char *
4815 decode_Z80_machine_flags (char *out, unsigned int e_flags)
4817 switch (e_flags & EF_Z80_MACH_MSK)
4819 case EF_Z80_MACH_Z80:
4820 out = stpcpy (out, ", Z80");
4821 break;
4822 case EF_Z80_MACH_Z180:
4823 out = stpcpy (out, ", Z180");
4824 break;
4825 case EF_Z80_MACH_R800:
4826 out = stpcpy (out, ", R800");
4827 break;
4828 case EF_Z80_MACH_EZ80_Z80:
4829 out = stpcpy (out, ", EZ80");
4830 break;
4831 case EF_Z80_MACH_EZ80_ADL:
4832 out = stpcpy (out, ", EZ80, ADL");
4833 break;
4834 case EF_Z80_MACH_GBZ80:
4835 out = stpcpy (out, ", GBZ80");
4836 break;
4837 case EF_Z80_MACH_Z80N:
4838 out = stpcpy (out, ", Z80N");
4839 break;
4840 default:
4841 out = stpcpy (out, _(", unknown"));
4842 break;
4844 return out;
4847 static char *
4848 decode_AMDGPU_machine_flags (char *out, unsigned int e_flags, Filedata *filedata)
4850 unsigned char *e_ident = filedata->file_header.e_ident;
4851 unsigned char osabi = e_ident[EI_OSABI];
4852 unsigned char abiversion = e_ident[EI_ABIVERSION];
4853 unsigned int mach;
4855 /* HSA OS ABI v2 used a different encoding, but we don't need to support it,
4856 it has been deprecated for a while.
4858 The PAL, MESA3D and NONE OS ABIs are not properly versioned, at the time
4859 of writing, they use the same flags as HSA v3, so the code below uses that
4860 assumption. */
4861 if (osabi == ELFOSABI_AMDGPU_HSA && abiversion < ELFABIVERSION_AMDGPU_HSA_V3)
4862 return out;
4864 mach = e_flags & EF_AMDGPU_MACH;
4865 switch (mach)
4867 #define AMDGPU_CASE(code, string) \
4868 case code: out = stpcpy (out, ", " string); break;
4869 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600")
4870 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601")
4871 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700")
4872 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701")
4873 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702")
4874 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703")
4875 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704")
4876 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801")
4877 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802")
4878 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803")
4879 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810")
4880 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900")
4881 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902")
4882 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904")
4883 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906")
4884 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908")
4885 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909")
4886 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c")
4887 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010")
4888 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011")
4889 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012")
4890 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030")
4891 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031")
4892 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032")
4893 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033")
4894 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1100, "gfx1100")
4895 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1101, "gfx1101")
4896 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1102, "gfx1102")
4897 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602")
4898 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705")
4899 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805")
4900 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035")
4901 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034")
4902 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a")
4903 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940")
4904 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013")
4905 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036")
4906 default:
4907 out += sprintf (out, _(", <unknown AMDGPU GPU type: %#x>"), mach);
4908 break;
4909 #undef AMDGPU_CASE
4912 e_flags &= ~EF_AMDGPU_MACH;
4914 if ((osabi == ELFOSABI_AMDGPU_HSA
4915 && abiversion == ELFABIVERSION_AMDGPU_HSA_V3)
4916 || osabi != ELFOSABI_AMDGPU_HSA)
4918 /* For HSA v3 and other OS ABIs. */
4919 if (e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
4921 out = stpcpy (out, ", xnack on");
4922 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V3;
4925 if (e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
4927 out = stpcpy (out, ", sramecc on");
4928 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V3;
4931 else
4933 /* For HSA v4+. */
4934 int xnack, sramecc;
4936 xnack = e_flags & EF_AMDGPU_FEATURE_XNACK_V4;
4937 switch (xnack)
4939 case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
4940 break;
4942 case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
4943 out = stpcpy (out, ", xnack any");
4944 break;
4946 case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
4947 out = stpcpy (out, ", xnack off");
4948 break;
4950 case EF_AMDGPU_FEATURE_XNACK_ON_V4:
4951 out = stpcpy (out, ", xnack on");
4952 break;
4954 default:
4955 out += sprintf (out, _(", <unknown xnack value: %#x>"), xnack);
4956 break;
4959 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V4;
4961 sramecc = e_flags & EF_AMDGPU_FEATURE_SRAMECC_V4;
4962 switch (sramecc)
4964 case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
4965 break;
4967 case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
4968 out = stpcpy (out, ", sramecc any");
4969 break;
4971 case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
4972 out = stpcpy (out, ", sramecc off");
4973 break;
4975 case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
4976 out = stpcpy (out, ", sramecc on");
4977 break;
4979 default:
4980 out += sprintf (out, _(", <unknown sramecc value: %#x>"), sramecc);
4981 break;
4984 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V4;
4987 if (e_flags != 0)
4988 out += sprintf (out, _(", unknown flags bits: %#x"), e_flags);
4989 return out;
4992 static char *
4993 get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
4995 static char buf[1024];
4996 char *out = buf;
4998 buf[0] = '\0';
5000 if (e_flags)
5002 switch (e_machine)
5004 default:
5005 break;
5007 case EM_ARC_COMPACT3:
5008 out = stpcpy (out, ", HS5x");
5009 break;
5011 case EM_ARC_COMPACT3_64:
5012 out = stpcpy (out, ", HS6x");
5013 break;
5015 case EM_ARC_COMPACT2:
5016 case EM_ARC_COMPACT:
5017 out = decode_ARC_machine_flags (out, e_flags, e_machine);
5018 break;
5020 case EM_ARM:
5021 out = decode_ARM_machine_flags (out, e_flags);
5022 break;
5024 case EM_AVR:
5025 out = decode_AVR_machine_flags (out, e_flags);
5026 break;
5028 case EM_BLACKFIN:
5029 out = decode_BLACKFIN_machine_flags (out, e_flags);
5030 break;
5032 case EM_CYGNUS_FRV:
5033 out = decode_FRV_machine_flags (out, e_flags);
5034 break;
5036 case EM_68K:
5037 out = decode_M68K_machine_flags (out, e_flags);
5038 break;
5040 case EM_AMDGPU:
5041 out = decode_AMDGPU_machine_flags (out, e_flags, filedata);
5042 break;
5044 case EM_CYGNUS_MEP:
5045 out = decode_MeP_machine_flags (out, e_flags);
5046 break;
5048 case EM_PPC:
5049 if (e_flags & EF_PPC_EMB)
5050 out = stpcpy (out, ", emb");
5052 if (e_flags & EF_PPC_RELOCATABLE)
5053 out = stpcpy (out, _(", relocatable"));
5055 if (e_flags & EF_PPC_RELOCATABLE_LIB)
5056 out = stpcpy (out, _(", relocatable-lib"));
5057 break;
5059 case EM_PPC64:
5060 if (e_flags & EF_PPC64_ABI)
5061 out += sprintf (out, ", abiv%d", e_flags & EF_PPC64_ABI);
5062 break;
5064 case EM_V800:
5065 out = decode_V800_machine_flags (out, e_flags);
5066 break;
5068 case EM_V850:
5069 case EM_CYGNUS_V850:
5070 out = decode_V850_machine_flags (out, e_flags);
5071 break;
5073 case EM_M32R:
5074 case EM_CYGNUS_M32R:
5075 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
5076 out = stpcpy (out, ", m32r");
5077 break;
5079 case EM_MIPS:
5080 case EM_MIPS_RS3_LE:
5081 out = decode_MIPS_machine_flags (out, e_flags);
5082 break;
5084 case EM_NDS32:
5085 out = decode_NDS32_machine_flags (out, e_flags);
5086 break;
5088 case EM_NFP:
5089 switch (EF_NFP_MACH (e_flags))
5091 case E_NFP_MACH_3200:
5092 out = stpcpy (out, ", NFP-32xx");
5093 break;
5094 case E_NFP_MACH_6000:
5095 out = stpcpy (out, ", NFP-6xxx");
5096 break;
5098 break;
5100 case EM_RISCV:
5101 out = decode_RISCV_machine_flags (out, e_flags);
5102 break;
5104 case EM_SH:
5105 out = decode_SH_machine_flags (out, e_flags);
5106 break;
5108 case EM_OR1K:
5109 if (e_flags & EF_OR1K_NODELAY)
5110 out = stpcpy (out, ", no delay");
5111 break;
5113 case EM_BPF:
5114 out += sprintf (out, ", CPU Version: %u", e_flags & EF_BPF_CPUVER);
5115 break;
5117 case EM_SPARCV9:
5118 out = decode_SPARC_machine_flags (out, e_flags);
5119 break;
5121 case EM_PARISC:
5122 out = decode_PARISC_machine_flags (out, e_flags);
5123 break;
5125 case EM_PJ:
5126 case EM_PJ_OLD:
5127 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
5128 out = stpcpy (out, ", new calling convention");
5130 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
5131 out = stpcpy (out, ", gnu calling convention");
5132 break;
5134 case EM_IA_64:
5135 out = decode_IA64_machine_flags (out, e_flags, filedata);
5136 break;
5138 case EM_VAX:
5139 if ((e_flags & EF_VAX_NONPIC))
5140 out = stpcpy (out, ", non-PIC");
5141 if ((e_flags & EF_VAX_DFLOAT))
5142 out = stpcpy (out, ", D-Float");
5143 if ((e_flags & EF_VAX_GFLOAT))
5144 out = stpcpy (out, ", G-Float");
5145 break;
5147 case EM_VISIUM:
5148 if (e_flags & EF_VISIUM_ARCH_MCM)
5149 out = stpcpy (out, ", mcm");
5150 else if (e_flags & EF_VISIUM_ARCH_MCM24)
5151 out = stpcpy (out, ", mcm24");
5152 if (e_flags & EF_VISIUM_ARCH_GR6)
5153 out = stpcpy (out, ", gr6");
5154 break;
5156 case EM_RL78:
5157 out = decode_RL78_machine_flags (out, e_flags);
5158 break;
5160 case EM_RX:
5161 out = decode_RX_machine_flags (out, e_flags);
5162 break;
5164 case EM_S390:
5165 if (e_flags & EF_S390_HIGH_GPRS)
5166 out = stpcpy (out, ", highgprs");
5167 break;
5169 case EM_TI_C6000:
5170 if ((e_flags & EF_C6000_REL))
5171 out = stpcpy (out, ", relocatable module");
5172 break;
5174 case EM_KVX:
5175 if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV3_1)
5176 strcat (buf, ", Kalray VLIW kv3-1");
5177 else if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV3_2)
5178 strcat (buf, ", Kalray VLIW kv3-2");
5179 else if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV4_1)
5180 strcat (buf, ", Kalray VLIW kv4-1");
5181 else
5182 strcat (buf, ", unknown KVX MPPA");
5183 break;
5185 case EM_MSP430:
5186 out = decode_MSP430_machine_flags (out, e_flags);
5187 break;
5189 case EM_Z80:
5190 out = decode_Z80_machine_flags (out, e_flags);
5191 break;
5193 case EM_LOONGARCH:
5194 out = decode_LOONGARCH_machine_flags (out, e_flags);
5195 break;
5199 return buf;
5202 static const char *
5203 get_osabi_name (Filedata * filedata, unsigned int osabi)
5205 static char buff[32];
5207 switch (osabi)
5209 case ELFOSABI_NONE: return "UNIX - System V";
5210 case ELFOSABI_HPUX: return "UNIX - HP-UX";
5211 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
5212 case ELFOSABI_GNU: return "UNIX - GNU";
5213 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
5214 case ELFOSABI_AIX: return "UNIX - AIX";
5215 case ELFOSABI_IRIX: return "UNIX - IRIX";
5216 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
5217 case ELFOSABI_TRU64: return "UNIX - TRU64";
5218 case ELFOSABI_MODESTO: return "Novell - Modesto";
5219 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
5220 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
5221 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
5222 case ELFOSABI_AROS: return "AROS";
5223 case ELFOSABI_FENIXOS: return "FenixOS";
5224 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
5225 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
5226 case ELFOSABI_CUDA: return "CUDA";
5227 default:
5228 if (osabi >= 64)
5229 switch (filedata->file_header.e_machine)
5231 case EM_AMDGPU:
5232 switch (osabi)
5234 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
5235 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
5236 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
5237 default:
5238 break;
5240 break;
5242 case EM_ARM:
5243 switch (osabi)
5245 case ELFOSABI_ARM: return "ARM";
5246 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
5247 default:
5248 break;
5250 break;
5252 case EM_MSP430:
5253 case EM_MSP430_OLD:
5254 case EM_VISIUM:
5255 switch (osabi)
5257 case ELFOSABI_STANDALONE: return _("Standalone App");
5258 default:
5259 break;
5261 break;
5263 case EM_TI_C6000:
5264 switch (osabi)
5266 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
5267 case ELFOSABI_C6000_LINUX: return "Linux C6000";
5268 default:
5269 break;
5271 break;
5273 default:
5274 break;
5276 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
5277 return buff;
5281 static const char *
5282 get_aarch64_segment_type (unsigned long type)
5284 switch (type)
5286 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
5287 case PT_AARCH64_MEMTAG_MTE: return "AARCH64_MEMTAG_MTE";
5288 default: return NULL;
5292 static const char *
5293 get_arm_segment_type (unsigned long type)
5295 switch (type)
5297 case PT_ARM_ARCHEXT: return "ARM_ARCHEXT";
5298 case PT_ARM_EXIDX: return "ARM_EXIDX";
5299 default: return NULL;
5303 static const char *
5304 get_s390_segment_type (unsigned long type)
5306 switch (type)
5308 case PT_S390_PGSTE: return "S390_PGSTE";
5309 default: return NULL;
5313 static const char *
5314 get_mips_segment_type (unsigned long type)
5316 switch (type)
5318 case PT_MIPS_REGINFO: return "REGINFO";
5319 case PT_MIPS_RTPROC: return "RTPROC";
5320 case PT_MIPS_OPTIONS: return "OPTIONS";
5321 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
5322 default: return NULL;
5326 static const char *
5327 get_parisc_segment_type (unsigned long type)
5329 switch (type)
5331 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
5332 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
5333 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
5334 default: return NULL;
5338 static const char *
5339 get_ia64_segment_type (unsigned long type)
5341 switch (type)
5343 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
5344 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
5345 default: return NULL;
5349 static const char *
5350 get_tic6x_segment_type (unsigned long type)
5352 switch (type)
5354 case PT_C6000_PHATTR: return "C6000_PHATTR";
5355 default: return NULL;
5359 static const char *
5360 get_riscv_segment_type (unsigned long type)
5362 switch (type)
5364 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5365 default: return NULL;
5369 static const char *
5370 get_hpux_segment_type (unsigned long type, unsigned e_machine)
5372 if (e_machine == EM_PARISC)
5373 switch (type)
5375 case PT_HP_TLS: return "HP_TLS";
5376 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
5377 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
5378 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
5379 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
5380 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
5381 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
5382 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
5383 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
5384 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
5385 case PT_HP_PARALLEL: return "HP_PARALLEL";
5386 case PT_HP_FASTBIND: return "HP_FASTBIND";
5387 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
5388 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
5389 case PT_HP_STACK: return "HP_STACK";
5390 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
5391 default:
5392 break;
5395 if (e_machine == EM_IA_64)
5396 switch (type)
5398 case PT_HP_TLS: return "HP_TLS";
5399 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
5400 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
5401 case PT_IA_64_HP_STACK: return "HP_STACK";
5402 default:
5403 break;
5406 return NULL;
5409 static const char *
5410 get_solaris_segment_type (unsigned long type)
5412 switch (type)
5414 case PT_SUNW_UNWIND: return "SUNW_UNWIND";
5415 case PT_SUNW_EH_FRAME: return "SUNW_EH_FRAME";
5416 case PT_SUNWBSS: return "SUNW_BSS";
5417 case PT_SUNWSTACK: return "SUNW_STACK";
5418 case PT_SUNWDTRACE: return "SUNW_DTRACE";
5419 case PT_SUNWCAP: return "SUNW_CAP";
5420 default: return NULL;
5424 static const char *
5425 get_os_specific_segment_type (Filedata * filedata, unsigned long p_type)
5427 static char buff[32];
5428 const char * result = NULL;
5430 switch (filedata->file_header.e_ident[EI_OSABI])
5432 case ELFOSABI_GNU:
5433 case ELFOSABI_FREEBSD:
5434 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
5436 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
5437 result = buff;
5439 break;
5441 case ELFOSABI_HPUX:
5442 result = get_hpux_segment_type (p_type,
5443 filedata->file_header.e_machine);
5444 break;
5446 case ELFOSABI_SOLARIS:
5447 result = get_solaris_segment_type (p_type);
5448 break;
5450 default:
5451 break;
5454 if (result != NULL)
5455 return result;
5457 switch (p_type)
5459 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
5460 case PT_GNU_STACK: return "GNU_STACK";
5461 case PT_GNU_RELRO: return "GNU_RELRO";
5462 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
5463 case PT_GNU_SFRAME: return "GNU_SFRAME";
5465 case PT_OPENBSD_MUTABLE: return "OPENBSD_MUTABLE";
5466 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
5467 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
5468 case PT_OPENBSD_NOBTCFI: return "OPENBSD_NOBTCFI";
5469 case PT_OPENBSD_SYSCALLS: return "OPENBSD_SYSCALLS";
5470 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
5472 default:
5473 break;
5476 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
5477 return buff;
5480 static const char *
5481 get_processor_specific_segment_type (Filedata * filedata, unsigned long p_type)
5483 static char buff[32];
5484 const char * result = NULL;
5486 switch (filedata->file_header.e_machine)
5488 case EM_AARCH64:
5489 result = get_aarch64_segment_type (p_type);
5490 break;
5492 case EM_ARM:
5493 result = get_arm_segment_type (p_type);
5494 break;
5496 case EM_MIPS:
5497 case EM_MIPS_RS3_LE:
5498 result = get_mips_segment_type (p_type);
5499 break;
5501 case EM_PARISC:
5502 result = get_parisc_segment_type (p_type);
5503 break;
5505 case EM_IA_64:
5506 result = get_ia64_segment_type (p_type);
5507 break;
5509 case EM_TI_C6000:
5510 result = get_tic6x_segment_type (p_type);
5511 break;
5513 case EM_S390:
5514 case EM_S390_OLD:
5515 result = get_s390_segment_type (p_type);
5516 break;
5518 case EM_RISCV:
5519 result = get_riscv_segment_type (p_type);
5520 break;
5522 default:
5523 result = NULL;
5524 break;
5527 if (result != NULL)
5528 return result;
5530 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
5531 return buff;
5534 static const char *
5535 get_segment_type (Filedata * filedata, unsigned long p_type)
5537 static char buff[32];
5539 switch (p_type)
5541 case PT_NULL: return "NULL";
5542 case PT_LOAD: return "LOAD";
5543 case PT_DYNAMIC: return "DYNAMIC";
5544 case PT_INTERP: return "INTERP";
5545 case PT_NOTE: return "NOTE";
5546 case PT_SHLIB: return "SHLIB";
5547 case PT_PHDR: return "PHDR";
5548 case PT_TLS: return "TLS";
5549 case PT_NUM: return "NUM";
5552 if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
5553 return get_os_specific_segment_type (filedata, p_type);
5555 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
5556 return get_processor_specific_segment_type (filedata, p_type);
5558 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
5559 return buff;
5562 static const char *
5563 get_arc_section_type_name (unsigned int sh_type)
5565 switch (sh_type)
5567 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
5568 default:
5569 break;
5571 return NULL;
5574 static const char *
5575 get_mips_section_type_name (unsigned int sh_type)
5577 switch (sh_type)
5579 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
5580 case SHT_MIPS_MSYM: return "MIPS_MSYM";
5581 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
5582 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
5583 case SHT_MIPS_UCODE: return "MIPS_UCODE";
5584 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
5585 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
5586 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
5587 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
5588 case SHT_MIPS_RELD: return "MIPS_RELD";
5589 case SHT_MIPS_IFACE: return "MIPS_IFACE";
5590 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
5591 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
5592 case SHT_MIPS_SHDR: return "MIPS_SHDR";
5593 case SHT_MIPS_FDESC: return "MIPS_FDESC";
5594 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
5595 case SHT_MIPS_DENSE: return "MIPS_DENSE";
5596 case SHT_MIPS_PDESC: return "MIPS_PDESC";
5597 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
5598 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
5599 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
5600 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
5601 case SHT_MIPS_LINE: return "MIPS_LINE";
5602 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
5603 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
5604 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
5605 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
5606 case SHT_MIPS_DWARF: return "MIPS_DWARF";
5607 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
5608 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
5609 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
5610 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
5611 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
5612 case SHT_MIPS_XLATE: return "MIPS_XLATE";
5613 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
5614 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
5615 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
5616 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
5617 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
5618 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
5619 case SHT_MIPS_XHASH: return "MIPS_XHASH";
5620 default:
5621 break;
5623 return NULL;
5626 static const char *
5627 get_parisc_section_type_name (unsigned int sh_type)
5629 switch (sh_type)
5631 case SHT_PARISC_EXT: return "PARISC_EXT";
5632 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
5633 case SHT_PARISC_DOC: return "PARISC_DOC";
5634 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
5635 case SHT_PARISC_DLKM: return "PARISC_DLKM";
5636 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
5637 case SHT_PARISC_STUBS: return "PARISC_STUBS";
5638 default: return NULL;
5642 static const char *
5643 get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
5645 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
5646 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
5647 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
5649 switch (sh_type)
5651 case SHT_IA_64_EXT: return "IA_64_EXT";
5652 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
5653 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
5654 default:
5655 break;
5657 return NULL;
5660 static const char *
5661 get_vms_section_type_name (unsigned int sh_type)
5663 switch (sh_type)
5665 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
5666 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
5667 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
5668 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
5669 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
5670 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
5671 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
5672 default:
5673 break;
5675 return NULL;
5678 static const char *
5679 get_x86_64_section_type_name (unsigned int sh_type)
5681 switch (sh_type)
5683 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
5684 default: return NULL;
5688 static const char *
5689 get_aarch64_section_type_name (unsigned int sh_type)
5691 switch (sh_type)
5693 case SHT_AARCH64_ATTRIBUTES:
5694 return "AARCH64_ATTRIBUTES";
5695 case SHT_AARCH64_AUTH_RELR:
5696 return "AARCH64_AUTH_RELR";
5697 case SHT_AARCH64_MEMTAG_GLOBALS_STATIC:
5698 return "AARCH64_MEMTAG_GLOBALS_STATIC";
5699 case SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC:
5700 return "AARCH64_MEMTAG_GLOBALS_DYNAMIC";
5701 default:
5702 return NULL;
5706 static const char *
5707 get_arm_section_type_name (unsigned int sh_type)
5709 switch (sh_type)
5711 case SHT_ARM_EXIDX: return "ARM_EXIDX";
5712 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
5713 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
5714 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
5715 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
5716 default: return NULL;
5720 static const char *
5721 get_tic6x_section_type_name (unsigned int sh_type)
5723 switch (sh_type)
5725 case SHT_C6000_UNWIND: return "C6000_UNWIND";
5726 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
5727 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
5728 case SHT_TI_ICODE: return "TI_ICODE";
5729 case SHT_TI_XREF: return "TI_XREF";
5730 case SHT_TI_HANDLER: return "TI_HANDLER";
5731 case SHT_TI_INITINFO: return "TI_INITINFO";
5732 case SHT_TI_PHATTRS: return "TI_PHATTRS";
5733 default: return NULL;
5737 static const char *
5738 get_msp430_section_type_name (unsigned int sh_type)
5740 switch (sh_type)
5742 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
5743 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
5744 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
5745 default: return NULL;
5749 static const char *
5750 get_nfp_section_type_name (unsigned int sh_type)
5752 switch (sh_type)
5754 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
5755 case SHT_NFP_INITREG: return "NFP_INITREG";
5756 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
5757 default: return NULL;
5761 static const char *
5762 get_v850_section_type_name (unsigned int sh_type)
5764 switch (sh_type)
5766 case SHT_V850_SCOMMON: return "V850 Small Common";
5767 case SHT_V850_TCOMMON: return "V850 Tiny Common";
5768 case SHT_V850_ZCOMMON: return "V850 Zero Common";
5769 case SHT_RENESAS_IOP: return "RENESAS IOP";
5770 case SHT_RENESAS_INFO: return "RENESAS INFO";
5771 default: return NULL;
5775 static const char *
5776 get_riscv_section_type_name (unsigned int sh_type)
5778 switch (sh_type)
5780 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5781 default: return NULL;
5785 static const char *
5786 get_csky_section_type_name (unsigned int sh_type)
5788 switch (sh_type)
5790 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
5791 default: return NULL;
5795 static const char *
5796 get_powerpc_section_type_name (unsigned int sh_type)
5798 switch (sh_type)
5800 case SHT_ORDERED: return "ORDERED";
5801 default: return NULL;
5805 static const char *
5806 get_alpha_section_type_name (unsigned int sh_type)
5808 switch (sh_type)
5810 case SHT_ALPHA_DEBUG: return "DEBUG";
5811 case SHT_ALPHA_REGINFO: return "REGINFO";
5812 default: return NULL;
5816 static const char *
5817 get_processor_specific_section_type_name (Filedata * filedata, unsigned int sh_type)
5819 static char buff[32];
5820 const char * result = NULL;
5822 switch (filedata->file_header.e_machine)
5824 case EM_AARCH64:
5825 result = get_aarch64_section_type_name (sh_type);
5826 break;
5828 case EM_ALPHA:
5829 result = get_alpha_section_type_name (sh_type);
5830 break;
5832 case EM_ARC:
5833 case EM_ARC_COMPACT:
5834 case EM_ARC_COMPACT2:
5835 case EM_ARC_COMPACT3:
5836 case EM_ARC_COMPACT3_64:
5837 result = get_arc_section_type_name (sh_type);
5838 break;
5840 case EM_ARM:
5841 result = get_arm_section_type_name (sh_type);
5842 break;
5844 case EM_CSKY:
5845 result = get_csky_section_type_name (sh_type);
5846 break;
5848 case EM_IA_64:
5849 result = get_ia64_section_type_name (filedata, sh_type);
5850 break;
5852 case EM_MIPS:
5853 case EM_MIPS_RS3_LE:
5854 result = get_mips_section_type_name (sh_type);
5855 break;
5857 case EM_MSP430:
5858 result = get_msp430_section_type_name (sh_type);
5859 break;
5861 case EM_NFP:
5862 result = get_nfp_section_type_name (sh_type);
5863 break;
5865 case EM_PARISC:
5866 result = get_parisc_section_type_name (sh_type);
5867 break;
5869 case EM_PPC64:
5870 case EM_PPC:
5871 return get_powerpc_section_type_name (sh_type);
5872 break;
5874 case EM_RISCV:
5875 result = get_riscv_section_type_name (sh_type);
5876 break;
5878 case EM_TI_C6000:
5879 result = get_tic6x_section_type_name (sh_type);
5880 break;
5882 case EM_V800:
5883 case EM_V850:
5884 case EM_CYGNUS_V850:
5885 result = get_v850_section_type_name (sh_type);
5886 break;
5888 case EM_X86_64:
5889 case EM_L1OM:
5890 case EM_K1OM:
5891 result = get_x86_64_section_type_name (sh_type);
5892 break;
5894 default:
5895 break;
5898 if (result != NULL)
5899 return result;
5901 switch (sh_type)
5903 /* FIXME: Are these correct ? If so, why do they not have #define's ? */
5904 case 0x7ffffffd: return "AUXILIARY";
5905 case 0x7fffffff: return "FILTER";
5906 default:
5907 break;
5910 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
5911 return buff;
5914 static const char *
5915 get_os_specific_section_type_name (Filedata * filedata, unsigned int sh_type)
5917 static char buff[32];
5918 const char * result = NULL;
5920 switch (filedata->file_header.e_machine)
5922 case EM_IA_64:
5923 result = get_vms_section_type_name (sh_type);
5924 break;
5925 default:
5926 break;
5929 if (result != NULL)
5930 return result;
5932 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
5933 result = get_solaris_section_type (sh_type);
5935 if (result != NULL)
5936 return result;
5938 switch (sh_type)
5940 case SHT_GNU_INCREMENTAL_INPUTS: return "GNU_INCREMENTAL_INPUTS";
5941 case SHT_GNU_ATTRIBUTES: return "GNU_ATTRIBUTES";
5942 case SHT_GNU_HASH: return "GNU_HASH";
5943 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
5945 case SHT_SUNW_move: return "SUNW_MOVE";
5946 case SHT_SUNW_COMDAT: return "SUNW_COMDAT";
5947 case SHT_SUNW_syminfo: return "SUNW_SYMINFO";
5948 case SHT_GNU_verdef: return "VERDEF";
5949 case SHT_GNU_verneed: return "VERNEED";
5950 case SHT_GNU_versym: return "VERSYM";
5952 case SHT_LLVM_ODRTAB: return "LLVM_ODRTAB";
5953 case SHT_LLVM_LINKER_OPTIONS: return "LLVM_LINKER_OPTIONS";
5954 case SHT_LLVM_ADDRSIG: return "LLVM_ADDRSIG";
5955 case SHT_LLVM_DEPENDENT_LIBRARIES: return "LLVM_DEPENDENT_LIBRARIES";
5956 case SHT_LLVM_SYMPART: return "LLVM_SYMPART";
5957 case SHT_LLVM_PART_EHDR: return "LLVM_PART_EHDR";
5958 case SHT_LLVM_PART_PHDR: return "LLVM_PART_PHDR";
5959 case SHT_LLVM_BB_ADDR_MAP_V0: return "LLVM_BB_ADDR_MAP_V0";
5960 case SHT_LLVM_CALL_GRAPH_PROFILE: return "LLVM_CALL_GRAPH_PROFILE";
5961 case SHT_LLVM_BB_ADDR_MAP: return "LLVM_BB_ADDR_MAP";
5962 case SHT_LLVM_OFFLOADING: return "LLVM_OFFLOADING";
5963 case SHT_LLVM_LTO: return "LLVM_LTO";
5965 case SHT_ANDROID_REL: return "ANDROID_REL";
5966 case SHT_ANDROID_RELA: return "ANDROID_RELA";
5967 case SHT_ANDROID_RELR: return "ANDROID_RELR";
5969 case SHT_CHECKSUM: return "CHECKSUM";
5971 /* FIXME: Are these correct ? If so, why do they not have #define's ? */
5972 case 0x6ffffff0: return "VERSYM";
5974 default:
5975 break;
5978 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
5979 return buff;
5982 static const char *
5983 get_user_specific_section_type_name (Filedata * filedata, unsigned int sh_type)
5985 static char buff[32];
5986 const char * result;
5988 switch (filedata->file_header.e_machine)
5990 case EM_V800:
5991 case EM_V850:
5992 case EM_CYGNUS_V850:
5993 result = get_v850_section_type_name (sh_type);
5994 break;
5996 default:
5997 result = NULL;
5998 break;
6001 if (result != NULL)
6002 return result;
6004 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
6005 return buff;
6008 static const char *
6009 get_section_type_name (Filedata * filedata,
6010 unsigned int sh_type)
6012 switch (sh_type)
6014 case SHT_NULL: return "NULL";
6015 case SHT_PROGBITS: return "PROGBITS";
6016 case SHT_SYMTAB: return "SYMTAB";
6017 case SHT_STRTAB: return "STRTAB";
6018 case SHT_RELA: return "RELA";
6019 case SHT_HASH: return "HASH";
6020 case SHT_DYNAMIC: return "DYNAMIC";
6021 case SHT_NOTE: return "NOTE";
6022 case SHT_NOBITS: return "NOBITS";
6023 case SHT_REL: return "REL";
6024 case SHT_SHLIB: return "SHLIB";
6025 case SHT_DYNSYM: return "DYNSYM";
6026 /* 12 and 13 are not defined. */
6027 case SHT_INIT_ARRAY: return "INIT_ARRAY";
6028 case SHT_FINI_ARRAY: return "FINI_ARRAY";
6029 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
6030 case SHT_GROUP: return "GROUP";
6031 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
6032 case SHT_RELR: return "RELR";
6033 /* End of generic section types. */
6035 default:
6036 break;
6039 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
6040 return get_processor_specific_section_type_name (filedata, sh_type);
6042 if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
6043 return get_os_specific_section_type_name (filedata, sh_type);
6045 if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
6046 return get_user_specific_section_type_name (filedata, sh_type);
6048 static char buff[32];
6050 /* This message is probably going to be displayed in a 15
6051 character wide field, so put the hex value first. */
6052 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
6053 return buff;
6056 enum long_option_values
6058 OPTION_DEBUG_DUMP = 512,
6059 OPTION_DYN_SYMS,
6060 OPTION_LTO_SYMS,
6061 OPTION_DWARF_DEPTH,
6062 OPTION_DWARF_START,
6063 OPTION_DWARF_CHECK,
6064 OPTION_CTF_DUMP,
6065 OPTION_CTF_PARENT,
6066 OPTION_CTF_SYMBOLS,
6067 OPTION_CTF_STRINGS,
6068 OPTION_SFRAME_DUMP,
6069 OPTION_WITH_SYMBOL_VERSIONS,
6070 OPTION_RECURSE_LIMIT,
6071 OPTION_NO_RECURSE_LIMIT,
6072 OPTION_NO_DEMANGLING,
6073 OPTION_NO_EXTRA_SYM_INFO,
6074 OPTION_SYM_BASE
6077 static struct option options[] =
6079 /* Note - This table is alpha-sorted on the 'val'
6080 field in order to make adding new options easier. */
6081 {"arch-specific", no_argument, 0, 'A'},
6082 {"all", no_argument, 0, 'a'},
6083 {"demangle", optional_argument, 0, 'C'},
6084 {"archive-index", no_argument, 0, 'c'},
6085 {"use-dynamic", no_argument, 0, 'D'},
6086 {"dynamic", no_argument, 0, 'd'},
6087 {"headers", no_argument, 0, 'e'},
6088 {"section-groups", no_argument, 0, 'g'},
6089 {"help", no_argument, 0, 'H'},
6090 {"file-header", no_argument, 0, 'h'},
6091 {"histogram", no_argument, 0, 'I'},
6092 {"display-section", required_argument, 0, 'j'},
6093 {"lint", no_argument, 0, 'L'},
6094 {"enable-checks", no_argument, 0, 'L'},
6095 {"program-headers", no_argument, 0, 'l'},
6096 {"segments", no_argument, 0, 'l'},
6097 {"full-section-name",no_argument, 0, 'N'},
6098 {"notes", no_argument, 0, 'n'},
6099 {"process-links", no_argument, 0, 'P'},
6100 {"string-dump", required_argument, 0, 'p'},
6101 {"relocated-dump", required_argument, 0, 'R'},
6102 {"relocs", no_argument, 0, 'r'},
6103 {"section-headers", no_argument, 0, 'S'},
6104 {"sections", no_argument, 0, 'S'},
6105 {"symbols", no_argument, 0, 's'},
6106 {"syms", no_argument, 0, 's'},
6107 {"silent-truncation",no_argument, 0, 'T'},
6108 {"section-details", no_argument, 0, 't'},
6109 {"unicode", required_argument, NULL, 'U'},
6110 {"unwind", no_argument, 0, 'u'},
6111 {"version-info", no_argument, 0, 'V'},
6112 {"version", no_argument, 0, 'v'},
6113 {"wide", no_argument, 0, 'W'},
6114 {"extra-sym-info", no_argument, 0, 'X'},
6115 {"hex-dump", required_argument, 0, 'x'},
6116 {"decompress", no_argument, 0, 'z'},
6118 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
6119 {"no-extra-sym-info",no_argument, 0, OPTION_NO_EXTRA_SYM_INFO},
6120 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
6121 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
6122 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
6123 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
6124 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
6125 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
6126 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
6127 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
6128 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
6129 #ifdef ENABLE_LIBCTF
6130 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
6131 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
6132 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
6133 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
6134 #endif
6135 {"sframe", optional_argument, 0, OPTION_SFRAME_DUMP},
6136 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
6138 {0, no_argument, 0, 0}
6141 static void
6142 usage (FILE * stream)
6144 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
6145 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
6146 fprintf (stream, _(" Options are:\n"));
6147 fprintf (stream, _("\
6148 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
6149 fprintf (stream, _("\
6150 -h --file-header Display the ELF file header\n"));
6151 fprintf (stream, _("\
6152 -l --program-headers Display the program headers\n"));
6153 fprintf (stream, _("\
6154 --segments An alias for --program-headers\n"));
6155 fprintf (stream, _("\
6156 -S --section-headers Display the sections' header\n"));
6157 fprintf (stream, _("\
6158 --sections An alias for --section-headers\n"));
6159 fprintf (stream, _("\
6160 -g --section-groups Display the section groups\n"));
6161 fprintf (stream, _("\
6162 -t --section-details Display the section details\n"));
6163 fprintf (stream, _("\
6164 -e --headers Equivalent to: -h -l -S\n"));
6165 fprintf (stream, _("\
6166 -s --syms Display the symbol table\n"));
6167 fprintf (stream, _("\
6168 --symbols An alias for --syms\n"));
6169 fprintf (stream, _("\
6170 --dyn-syms Display the dynamic symbol table\n"));
6171 fprintf (stream, _("\
6172 --lto-syms Display LTO symbol tables\n"));
6173 fprintf (stream, _("\
6174 --sym-base=[0|8|10|16] \n\
6175 Force base for symbol sizes. The options are \n\
6176 mixed (the default), octal, decimal, hexadecimal.\n"));
6177 fprintf (stream, _("\
6178 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
6179 display_demangler_styles (stream, _("\
6180 STYLE can be "));
6181 fprintf (stream, _("\
6182 --no-demangle Do not demangle low-level symbol names. (default)\n"));
6183 fprintf (stream, _("\
6184 --recurse-limit Enable a demangling recursion limit. (default)\n"));
6185 fprintf (stream, _("\
6186 --no-recurse-limit Disable a demangling recursion limit\n"));
6187 fprintf (stream, _("\
6188 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
6189 Display unicode characters as determined by the current locale\n\
6190 (default), escape sequences, \"<hex sequences>\", highlighted\n\
6191 escape sequences, or treat them as invalid and display as\n\
6192 \"{hex sequences}\"\n"));
6193 fprintf (stream, _("\
6194 -X --extra-sym-info Display extra information when showing symbols\n"));
6195 fprintf (stream, _("\
6196 --no-extra-sym-info Do not display extra information when showing symbols (default)\n"));
6197 fprintf (stream, _("\
6198 -n --notes Display the contents of note sections (if present)\n"));
6199 fprintf (stream, _("\
6200 -r --relocs Display the relocations (if present)\n"));
6201 fprintf (stream, _("\
6202 -u --unwind Display the unwind info (if present)\n"));
6203 fprintf (stream, _("\
6204 -d --dynamic Display the dynamic section (if present)\n"));
6205 fprintf (stream, _("\
6206 -V --version-info Display the version sections (if present)\n"));
6207 fprintf (stream, _("\
6208 -A --arch-specific Display architecture specific information (if any)\n"));
6209 fprintf (stream, _("\
6210 -c --archive-index Display the symbol/file index in an archive\n"));
6211 fprintf (stream, _("\
6212 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
6213 fprintf (stream, _("\
6214 -L --lint|--enable-checks\n\
6215 Display warning messages for possible problems\n"));
6216 fprintf (stream, _("\
6217 -x --hex-dump=<number|name>\n\
6218 Dump the contents of section <number|name> as bytes\n"));
6219 fprintf (stream, _("\
6220 -p --string-dump=<number|name>\n\
6221 Dump the contents of section <number|name> as strings\n"));
6222 fprintf (stream, _("\
6223 -R --relocated-dump=<number|name>\n\
6224 Dump the relocated contents of section <number|name>\n"));
6225 fprintf (stream, _("\
6226 -z --decompress Decompress section before dumping it\n"));
6227 fprintf (stream, _("\n\
6228 -j --display-section=<name|number>\n\
6229 Display the contents of the indicated section. Can be repeated\n"));
6230 fprintf (stream, _("\
6231 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
6232 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
6233 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
6234 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
6235 U/=trace_info]\n\
6236 Display the contents of DWARF debug sections\n"));
6237 fprintf (stream, _("\
6238 -wk --debug-dump=links Display the contents of sections that link to separate\n\
6239 debuginfo files\n"));
6240 fprintf (stream, _("\
6241 -P --process-links Display the contents of non-debug sections in separate\n\
6242 debuginfo files. (Implies -wK)\n"));
6243 #if DEFAULT_FOR_FOLLOW_LINKS
6244 fprintf (stream, _("\
6245 -wK --debug-dump=follow-links\n\
6246 Follow links to separate debug info files (default)\n"));
6247 fprintf (stream, _("\
6248 -wN --debug-dump=no-follow-links\n\
6249 Do not follow links to separate debug info files\n"));
6250 #else
6251 fprintf (stream, _("\
6252 -wK --debug-dump=follow-links\n\
6253 Follow links to separate debug info files\n"));
6254 fprintf (stream, _("\
6255 -wN --debug-dump=no-follow-links\n\
6256 Do not follow links to separate debug info files\n\
6257 (default)\n"));
6258 #endif
6259 #if HAVE_LIBDEBUGINFOD
6260 fprintf (stream, _("\
6261 -wD --debug-dump=use-debuginfod\n\
6262 When following links, also query debuginfod servers (default)\n"));
6263 fprintf (stream, _("\
6264 -wE --debug-dump=do-not-use-debuginfod\n\
6265 When following links, do not query debuginfod servers\n"));
6266 #endif
6267 fprintf (stream, _("\
6268 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
6269 fprintf (stream, _("\
6270 --dwarf-start=N Display DIEs starting at offset N\n"));
6271 #ifdef ENABLE_LIBCTF
6272 fprintf (stream, _("\
6273 --ctf=<number|name> Display CTF info from section <number|name>\n"));
6274 fprintf (stream, _("\
6275 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
6276 fprintf (stream, _("\
6277 --ctf-symbols=<number|name>\n\
6278 Use section <number|name> as the CTF external symtab\n"));
6279 fprintf (stream, _("\
6280 --ctf-strings=<number|name>\n\
6281 Use section <number|name> as the CTF external strtab\n"));
6282 #endif
6283 fprintf (stream, _("\
6284 --sframe[=NAME] Display SFrame info from section NAME, (default '.sframe')\n"));
6286 #ifdef SUPPORT_DISASSEMBLY
6287 fprintf (stream, _("\
6288 -i --instruction-dump=<number|name>\n\
6289 Disassemble the contents of section <number|name>\n"));
6290 #endif
6291 fprintf (stream, _("\
6292 -I --histogram Display histogram of bucket list lengths\n"));
6293 fprintf (stream, _("\
6294 -W --wide Allow output width to exceed 80 characters\n"));
6295 fprintf (stream, _("\
6296 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
6297 fprintf (stream, _("\
6298 @<file> Read options from <file>\n"));
6299 fprintf (stream, _("\
6300 -H --help Display this information\n"));
6301 fprintf (stream, _("\
6302 -v --version Display the version number of readelf\n"));
6304 if (REPORT_BUGS_TO[0] && stream == stdout)
6305 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
6307 exit (stream == stdout ? 0 : 1);
6310 /* Record the fact that the user wants the contents of section number
6311 SECTION to be displayed using the method(s) encoded as flags bits
6312 in TYPE. Note, TYPE can be zero if we are creating the array for
6313 the first time. */
6315 static void
6316 request_dump_bynumber (struct dump_data *dumpdata,
6317 unsigned int section, dump_type type)
6319 if (section >= dumpdata->num_dump_sects)
6321 dump_type * new_dump_sects;
6323 new_dump_sects = (dump_type *) calloc (section + 1,
6324 sizeof (* new_dump_sects));
6326 if (new_dump_sects == NULL)
6327 error (_("Out of memory allocating dump request table.\n"));
6328 else
6330 if (dumpdata->dump_sects)
6332 /* Copy current flag settings. */
6333 memcpy (new_dump_sects, dumpdata->dump_sects,
6334 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
6336 free (dumpdata->dump_sects);
6339 dumpdata->dump_sects = new_dump_sects;
6340 dumpdata->num_dump_sects = section + 1;
6344 if (dumpdata->dump_sects)
6345 dumpdata->dump_sects[section] |= type;
6348 /* Request a dump by section name. */
6350 static void
6351 request_dump_byname (const char * section, dump_type type)
6353 struct dump_list_entry * new_request;
6355 new_request = (struct dump_list_entry *)
6356 malloc (sizeof (struct dump_list_entry));
6357 if (!new_request)
6358 error (_("Out of memory allocating dump request table.\n"));
6360 new_request->name = strdup (section);
6361 if (!new_request->name)
6362 error (_("Out of memory allocating dump request table.\n"));
6364 new_request->type = type;
6366 new_request->next = dump_sects_byname;
6367 dump_sects_byname = new_request;
6370 static inline void
6371 request_dump (struct dump_data *dumpdata, dump_type type)
6373 int section;
6374 char * cp;
6376 do_dump = true;
6377 section = strtoul (optarg, & cp, 0);
6379 if (! *cp && section >= 0)
6380 request_dump_bynumber (dumpdata, section, type);
6381 else
6382 request_dump_byname (optarg, type);
6385 static void
6386 parse_args (struct dump_data *dumpdata, int argc, char ** argv)
6388 int c;
6390 if (argc < 2)
6391 usage (stderr);
6393 while ((c = getopt_long
6394 (argc, argv, "ACDHILNPR:STU:VWXacdeghi:j:lnp:rstuvw::x:z", options, NULL)) != EOF)
6396 switch (c)
6398 case 0:
6399 /* Long options. */
6400 break;
6401 case 'H':
6402 usage (stdout);
6403 break;
6405 case 'a':
6406 do_syms = true;
6407 do_reloc = true;
6408 do_unwind = true;
6409 do_dynamic = true;
6410 do_header = true;
6411 do_sections = true;
6412 do_section_groups = true;
6413 do_segments = true;
6414 do_version = true;
6415 do_histogram = true;
6416 do_arch = true;
6417 do_notes = true;
6418 break;
6420 case 'g':
6421 do_section_groups = true;
6422 break;
6423 case 't':
6424 case 'N':
6425 do_sections = true;
6426 do_section_details = true;
6427 break;
6428 case 'e':
6429 do_header = true;
6430 do_sections = true;
6431 do_segments = true;
6432 break;
6433 case 'A':
6434 do_arch = true;
6435 break;
6436 case 'D':
6437 do_using_dynamic = true;
6438 break;
6439 case 'r':
6440 do_reloc = true;
6441 break;
6442 case 'u':
6443 do_unwind = true;
6444 break;
6445 case 'h':
6446 do_header = true;
6447 break;
6448 case 'l':
6449 do_segments = true;
6450 break;
6451 case 's':
6452 do_syms = true;
6453 break;
6454 case 'S':
6455 do_sections = true;
6456 break;
6457 case 'd':
6458 do_dynamic = true;
6459 break;
6460 case 'I':
6461 do_histogram = true;
6462 break;
6463 case 'n':
6464 do_notes = true;
6465 break;
6466 case 'c':
6467 do_archive_index = true;
6468 break;
6469 case 'L':
6470 do_checks = true;
6471 break;
6472 case 'P':
6473 process_links = true;
6474 do_follow_links = true;
6475 dump_any_debugging = true;
6476 break;
6477 case 'j':
6478 request_dump (dumpdata, AUTO_DUMP);
6479 break;
6480 case 'x':
6481 request_dump (dumpdata, HEX_DUMP);
6482 break;
6483 case 'p':
6484 request_dump (dumpdata, STRING_DUMP);
6485 break;
6486 case 'R':
6487 request_dump (dumpdata, RELOC_DUMP);
6488 break;
6489 case 'z':
6490 decompress_dumps = true;
6491 break;
6492 case 'w':
6493 if (optarg == NULL)
6495 do_debugging = true;
6496 do_dump = true;
6497 dump_any_debugging = true;
6498 dwarf_select_sections_all ();
6500 else
6502 do_debugging = false;
6503 if (dwarf_select_sections_by_letters (optarg))
6505 do_dump = true;
6506 dump_any_debugging = true;
6509 break;
6510 case OPTION_DEBUG_DUMP:
6511 if (optarg == NULL)
6513 do_dump = true;
6514 do_debugging = true;
6515 dump_any_debugging = true;
6516 dwarf_select_sections_all ();
6518 else
6520 do_debugging = false;
6521 if (dwarf_select_sections_by_names (optarg))
6523 do_dump = true;
6524 dump_any_debugging = true;
6527 break;
6528 case OPTION_DWARF_DEPTH:
6530 char *cp;
6532 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
6534 break;
6535 case OPTION_DWARF_START:
6537 char *cp;
6539 dwarf_start_die = strtoul (optarg, & cp, 0);
6541 break;
6542 case OPTION_DWARF_CHECK:
6543 dwarf_check = true;
6544 break;
6545 case OPTION_CTF_DUMP:
6546 do_ctf = true;
6547 request_dump (dumpdata, CTF_DUMP);
6548 break;
6549 case OPTION_CTF_SYMBOLS:
6550 free (dump_ctf_symtab_name);
6551 dump_ctf_symtab_name = strdup (optarg);
6552 break;
6553 case OPTION_CTF_STRINGS:
6554 free (dump_ctf_strtab_name);
6555 dump_ctf_strtab_name = strdup (optarg);
6556 break;
6557 case OPTION_CTF_PARENT:
6558 free (dump_ctf_parent_name);
6559 dump_ctf_parent_name = strdup (optarg);
6560 break;
6561 case OPTION_SFRAME_DUMP:
6562 do_sframe = true;
6563 /* Providing section name is optional. request_dump (), however,
6564 thrives on non NULL optarg. Handle it explicitly here. */
6565 if (optarg != NULL)
6566 request_dump (dumpdata, SFRAME_DUMP);
6567 else
6569 do_dump = true;
6570 const char *sframe_sec_name = strdup (".sframe");
6571 request_dump_byname (sframe_sec_name, SFRAME_DUMP);
6573 break;
6574 case OPTION_DYN_SYMS:
6575 do_dyn_syms = true;
6576 break;
6577 case OPTION_LTO_SYMS:
6578 do_lto_syms = true;
6579 break;
6580 case 'X':
6581 extra_sym_info = true;
6582 break;
6583 case OPTION_NO_EXTRA_SYM_INFO:
6584 extra_sym_info = false;
6585 break;
6587 #ifdef SUPPORT_DISASSEMBLY
6588 case 'i':
6589 request_dump (dumpdata, DISASS_DUMP);
6590 break;
6591 #endif
6592 case 'v':
6593 print_version (program_name);
6594 break;
6595 case 'V':
6596 do_version = true;
6597 break;
6598 case 'W':
6599 do_wide = true;
6600 break;
6601 case 'T':
6602 do_not_show_symbol_truncation = true;
6603 break;
6604 case 'C':
6605 do_demangle = true;
6606 if (optarg != NULL)
6608 enum demangling_styles style;
6610 style = cplus_demangle_name_to_style (optarg);
6611 if (style == unknown_demangling)
6612 error (_("unknown demangling style `%s'"), optarg);
6614 cplus_demangle_set_style (style);
6616 break;
6617 case OPTION_NO_DEMANGLING:
6618 do_demangle = false;
6619 break;
6620 case OPTION_RECURSE_LIMIT:
6621 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
6622 break;
6623 case OPTION_NO_RECURSE_LIMIT:
6624 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
6625 break;
6626 case OPTION_WITH_SYMBOL_VERSIONS:
6627 /* Ignored for backward compatibility. */
6628 break;
6630 case 'U':
6631 if (optarg == NULL)
6632 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
6633 else if (streq (optarg, "default") || streq (optarg, "d"))
6634 unicode_display = unicode_default;
6635 else if (streq (optarg, "locale") || streq (optarg, "l"))
6636 unicode_display = unicode_locale;
6637 else if (streq (optarg, "escape") || streq (optarg, "e"))
6638 unicode_display = unicode_escape;
6639 else if (streq (optarg, "invalid") || streq (optarg, "i"))
6640 unicode_display = unicode_invalid;
6641 else if (streq (optarg, "hex") || streq (optarg, "x"))
6642 unicode_display = unicode_hex;
6643 else if (streq (optarg, "highlight") || streq (optarg, "h"))
6644 unicode_display = unicode_highlight;
6645 else
6646 error (_("invalid argument to -U/--unicode: %s"), optarg);
6647 break;
6649 case OPTION_SYM_BASE:
6650 sym_base = 0;
6651 if (optarg != NULL)
6653 sym_base = strtoul (optarg, NULL, 0);
6654 switch (sym_base)
6656 case 0:
6657 case 8:
6658 case 10:
6659 case 16:
6660 break;
6662 default:
6663 sym_base = 0;
6664 break;
6667 break;
6669 default:
6670 /* xgettext:c-format */
6671 error (_("Invalid option '-%c'\n"), c);
6672 /* Fall through. */
6673 case '?':
6674 usage (stderr);
6678 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
6679 && !do_segments && !do_header && !do_dump && !do_version
6680 && !do_histogram && !do_debugging && !do_arch && !do_notes
6681 && !do_section_groups && !do_archive_index
6682 && !do_dyn_syms && !do_lto_syms)
6684 if (do_checks)
6686 check_all = true;
6687 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
6688 do_segments = do_header = do_dump = do_version = true;
6689 do_histogram = do_debugging = do_arch = do_notes = true;
6690 do_section_groups = do_archive_index = do_dyn_syms = true;
6691 do_lto_syms = true;
6693 else
6694 usage (stderr);
6698 static const char *
6699 get_elf_class (unsigned int elf_class)
6701 static char buff[32];
6703 switch (elf_class)
6705 case ELFCLASSNONE: return _("none");
6706 case ELFCLASS32: return "ELF32";
6707 case ELFCLASS64: return "ELF64";
6708 default:
6709 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
6710 return buff;
6714 static const char *
6715 get_data_encoding (unsigned int encoding)
6717 static char buff[32];
6719 switch (encoding)
6721 case ELFDATANONE: return _("none");
6722 case ELFDATA2LSB: return _("2's complement, little endian");
6723 case ELFDATA2MSB: return _("2's complement, big endian");
6724 default:
6725 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
6726 return buff;
6730 static bool
6731 check_magic_number (Filedata * filedata, Elf_Internal_Ehdr * header)
6733 if (header->e_ident[EI_MAG0] == ELFMAG0
6734 && header->e_ident[EI_MAG1] == ELFMAG1
6735 && header->e_ident[EI_MAG2] == ELFMAG2
6736 && header->e_ident[EI_MAG3] == ELFMAG3)
6737 return true;
6739 /* Some compilers produce object files that are not in the ELF file format.
6740 As an aid to users of readelf, try to identify these cases and suggest
6741 alternative tools.
6743 FIXME: It is not clear if all four bytes are used as constant magic
6744 valus by all compilers. It may be necessary to recode this function if
6745 different tools use different length sequences. */
6747 static struct
6749 unsigned char magic[4];
6750 const char * obj_message;
6751 const char * ar_message;
6753 known_magic[] =
6755 { { 'B', 'C', 0xc0, 0xde },
6756 N_("This is a LLVM bitcode file - try using llvm-bcanalyzer\n"),
6757 N_("This is a LLVM bitcode file - try extracting and then using llvm-bcanalyzer\n")
6759 { { 'g', 'o', ' ', 'o' },
6760 N_("This is a GO binary file - try using 'go tool objdump' or 'go tool nm'\n"),
6761 NULL
6764 int i;
6766 for (i = ARRAY_SIZE (known_magic); i--;)
6768 if (header->e_ident[EI_MAG0] == known_magic[i].magic[0]
6769 && header->e_ident[EI_MAG1] == known_magic[i].magic[1]
6770 && header->e_ident[EI_MAG2] == known_magic[i].magic[2]
6771 && header->e_ident[EI_MAG3] == known_magic[i].magic[3])
6773 /* Some compiler's analyzer tools do not handle archives,
6774 so we provide two different kinds of error message. */
6775 if (filedata->archive_file_size > 0
6776 && known_magic[i].ar_message != NULL)
6777 error ("%s", known_magic[i].ar_message);
6778 else
6779 error ("%s", known_magic[i].obj_message);
6780 return false;
6784 error (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
6785 return false;
6788 /* Decode the data held in 'filedata->file_header'. */
6790 static bool
6791 process_file_header (Filedata * filedata)
6793 Elf_Internal_Ehdr * header = & filedata->file_header;
6795 if (! check_magic_number (filedata, header))
6796 return false;
6798 if (! filedata->is_separate)
6799 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
6801 if (do_header)
6803 unsigned i;
6805 if (filedata->is_separate)
6806 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
6807 else
6808 printf (_("ELF Header:\n"));
6809 printf (_(" Magic: "));
6810 for (i = 0; i < EI_NIDENT; i++)
6811 printf ("%2.2x ", header->e_ident[i]);
6812 printf ("\n");
6813 printf (_(" Class: %s\n"),
6814 get_elf_class (header->e_ident[EI_CLASS]));
6815 printf (_(" Data: %s\n"),
6816 get_data_encoding (header->e_ident[EI_DATA]));
6817 printf (_(" Version: %d%s\n"),
6818 header->e_ident[EI_VERSION],
6819 (header->e_ident[EI_VERSION] == EV_CURRENT
6820 ? _(" (current)")
6821 : (header->e_ident[EI_VERSION] != EV_NONE
6822 ? _(" <unknown>")
6823 : "")));
6824 printf (_(" OS/ABI: %s\n"),
6825 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
6826 printf (_(" ABI Version: %d\n"),
6827 header->e_ident[EI_ABIVERSION]);
6828 printf (_(" Type: %s\n"),
6829 get_file_type (filedata));
6830 printf (_(" Machine: %s\n"),
6831 get_machine_name (header->e_machine));
6832 printf (_(" Version: 0x%lx\n"),
6833 header->e_version);
6835 printf (_(" Entry point address: "));
6836 print_vma (header->e_entry, PREFIX_HEX);
6837 printf (_("\n Start of program headers: "));
6838 print_vma (header->e_phoff, DEC);
6839 printf (_(" (bytes into file)\n Start of section headers: "));
6840 print_vma (header->e_shoff, DEC);
6841 printf (_(" (bytes into file)\n"));
6843 printf (_(" Flags: 0x%lx%s\n"),
6844 header->e_flags,
6845 get_machine_flags (filedata, header->e_flags, header->e_machine));
6846 printf (_(" Size of this header: %u (bytes)\n"),
6847 header->e_ehsize);
6848 printf (_(" Size of program headers: %u (bytes)\n"),
6849 header->e_phentsize);
6850 printf (_(" Number of program headers: %u"),
6851 header->e_phnum);
6852 if (filedata->section_headers != NULL
6853 && header->e_phnum == PN_XNUM
6854 && filedata->section_headers[0].sh_info != 0)
6855 printf (" (%u)", filedata->section_headers[0].sh_info);
6856 putc ('\n', stdout);
6857 printf (_(" Size of section headers: %u (bytes)\n"),
6858 header->e_shentsize);
6859 printf (_(" Number of section headers: %u"),
6860 header->e_shnum);
6861 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
6863 header->e_shnum = filedata->section_headers[0].sh_size;
6864 printf (" (%u)", header->e_shnum);
6866 putc ('\n', stdout);
6867 printf (_(" Section header string table index: %u"),
6868 header->e_shstrndx);
6869 if (filedata->section_headers != NULL
6870 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
6872 header->e_shstrndx = filedata->section_headers[0].sh_link;
6873 printf (" (%u)", header->e_shstrndx);
6875 if (header->e_shstrndx != SHN_UNDEF
6876 && header->e_shstrndx >= header->e_shnum)
6878 header->e_shstrndx = SHN_UNDEF;
6879 printf (_(" <corrupt: out of range>"));
6881 putc ('\n', stdout);
6884 if (filedata->section_headers != NULL)
6886 if (header->e_phnum == PN_XNUM
6887 && filedata->section_headers[0].sh_info != 0)
6889 /* Throw away any cached read of PN_XNUM headers. */
6890 free (filedata->program_headers);
6891 filedata->program_headers = NULL;
6892 header->e_phnum = filedata->section_headers[0].sh_info;
6894 if (header->e_shnum == SHN_UNDEF)
6895 header->e_shnum = filedata->section_headers[0].sh_size;
6896 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
6897 header->e_shstrndx = filedata->section_headers[0].sh_link;
6898 if (header->e_shstrndx >= header->e_shnum)
6899 header->e_shstrndx = SHN_UNDEF;
6902 return true;
6905 /* Read in the program headers from FILEDATA and store them in PHEADERS.
6906 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
6908 static bool
6909 get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
6911 Elf32_External_Phdr * phdrs;
6912 Elf32_External_Phdr * external;
6913 Elf_Internal_Phdr * internal;
6914 unsigned int i;
6915 unsigned int size = filedata->file_header.e_phentsize;
6916 unsigned int num = filedata->file_header.e_phnum;
6918 /* PR binutils/17531: Cope with unexpected section header sizes. */
6919 if (size == 0 || num == 0)
6920 return false;
6921 if (size < sizeof * phdrs)
6923 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
6924 return false;
6926 if (size > sizeof * phdrs)
6927 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
6929 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
6930 size, num, _("program headers"));
6931 if (phdrs == NULL)
6932 return false;
6934 for (i = 0, internal = pheaders, external = phdrs;
6935 i < filedata->file_header.e_phnum;
6936 i++, internal++, external++)
6938 internal->p_type = BYTE_GET (external->p_type);
6939 internal->p_offset = BYTE_GET (external->p_offset);
6940 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6941 internal->p_paddr = BYTE_GET (external->p_paddr);
6942 internal->p_filesz = BYTE_GET (external->p_filesz);
6943 internal->p_memsz = BYTE_GET (external->p_memsz);
6944 internal->p_flags = BYTE_GET (external->p_flags);
6945 internal->p_align = BYTE_GET (external->p_align);
6948 free (phdrs);
6949 return true;
6952 /* Read in the program headers from FILEDATA and store them in PHEADERS.
6953 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
6955 static bool
6956 get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
6958 Elf64_External_Phdr * phdrs;
6959 Elf64_External_Phdr * external;
6960 Elf_Internal_Phdr * internal;
6961 unsigned int i;
6962 unsigned int size = filedata->file_header.e_phentsize;
6963 unsigned int num = filedata->file_header.e_phnum;
6965 /* PR binutils/17531: Cope with unexpected section header sizes. */
6966 if (size == 0 || num == 0)
6967 return false;
6968 if (size < sizeof * phdrs)
6970 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
6971 return false;
6973 if (size > sizeof * phdrs)
6974 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
6976 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
6977 size, num, _("program headers"));
6978 if (!phdrs)
6979 return false;
6981 for (i = 0, internal = pheaders, external = phdrs;
6982 i < filedata->file_header.e_phnum;
6983 i++, internal++, external++)
6985 internal->p_type = BYTE_GET (external->p_type);
6986 internal->p_flags = BYTE_GET (external->p_flags);
6987 internal->p_offset = BYTE_GET (external->p_offset);
6988 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6989 internal->p_paddr = BYTE_GET (external->p_paddr);
6990 internal->p_filesz = BYTE_GET (external->p_filesz);
6991 internal->p_memsz = BYTE_GET (external->p_memsz);
6992 internal->p_align = BYTE_GET (external->p_align);
6995 free (phdrs);
6996 return true;
6999 /* Returns TRUE if the program headers were read into `program_headers'. */
7001 static bool
7002 get_program_headers (Filedata * filedata)
7004 Elf_Internal_Phdr * phdrs;
7006 /* Check cache of prior read. */
7007 if (filedata->program_headers != NULL)
7008 return true;
7010 /* Be kind to memory checkers by looking for
7011 e_phnum values which we know must be invalid. */
7012 if (filedata->file_header.e_phnum
7013 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
7014 >= filedata->file_size)
7016 error (_("Too many program headers - %#x - the file is not that big\n"),
7017 filedata->file_header.e_phnum);
7018 return false;
7021 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
7022 sizeof (Elf_Internal_Phdr));
7023 if (phdrs == NULL)
7025 error (_("Out of memory reading %u program headers\n"),
7026 filedata->file_header.e_phnum);
7027 return false;
7030 if (is_32bit_elf
7031 ? get_32bit_program_headers (filedata, phdrs)
7032 : get_64bit_program_headers (filedata, phdrs))
7034 filedata->program_headers = phdrs;
7035 return true;
7038 free (phdrs);
7039 return false;
7042 /* Print program header info and locate dynamic section. */
7044 static void
7045 process_program_headers (Filedata * filedata)
7047 Elf_Internal_Phdr * segment;
7048 unsigned int i;
7049 Elf_Internal_Phdr * previous_load = NULL;
7051 if (filedata->file_header.e_phnum == 0)
7053 /* PR binutils/12467. */
7054 if (filedata->file_header.e_phoff != 0)
7055 warn (_("possibly corrupt ELF header - it has a non-zero program"
7056 " header offset, but no program headers\n"));
7057 else if (do_segments)
7059 if (filedata->is_separate)
7060 printf (_("\nThere are no program headers in linked file '%s'.\n"),
7061 filedata->file_name);
7062 else
7063 printf (_("\nThere are no program headers in this file.\n"));
7065 goto no_headers;
7068 if (do_segments && !do_header)
7070 if (filedata->is_separate)
7071 printf ("\nIn linked file '%s' the ELF file type is %s\n",
7072 filedata->file_name, get_file_type (filedata));
7073 else
7074 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
7075 printf (_("Entry point 0x%" PRIx64 "\n"),
7076 filedata->file_header.e_entry);
7077 printf (ngettext ("There is %d program header,"
7078 " starting at offset %" PRIu64 "\n",
7079 "There are %d program headers,"
7080 " starting at offset %" PRIu64 "\n",
7081 filedata->file_header.e_phnum),
7082 filedata->file_header.e_phnum,
7083 filedata->file_header.e_phoff);
7086 if (! get_program_headers (filedata))
7087 goto no_headers;
7089 if (do_segments)
7091 if (filedata->file_header.e_phnum > 1)
7092 printf (_("\nProgram Headers:\n"));
7093 else
7094 printf (_("\nProgram Headers:\n"));
7096 if (is_32bit_elf)
7097 printf
7098 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
7099 else if (do_wide)
7100 printf
7101 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
7102 else
7104 printf
7105 (_(" Type Offset VirtAddr PhysAddr\n"));
7106 printf
7107 (_(" FileSiz MemSiz Flags Align\n"));
7111 uint64_t dynamic_addr = 0;
7112 uint64_t dynamic_size = 0;
7113 for (i = 0, segment = filedata->program_headers;
7114 i < filedata->file_header.e_phnum;
7115 i++, segment++)
7117 if (do_segments)
7119 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
7121 if (is_32bit_elf)
7123 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
7124 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
7125 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
7126 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
7127 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
7128 printf ("%c%c%c ",
7129 (segment->p_flags & PF_R ? 'R' : ' '),
7130 (segment->p_flags & PF_W ? 'W' : ' '),
7131 (segment->p_flags & PF_X ? 'E' : ' '));
7132 printf ("%#lx", (unsigned long) segment->p_align);
7134 else if (do_wide)
7136 if ((unsigned long) segment->p_offset == segment->p_offset)
7137 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
7138 else
7140 print_vma (segment->p_offset, FULL_HEX);
7141 putchar (' ');
7144 print_vma (segment->p_vaddr, FULL_HEX);
7145 putchar (' ');
7146 print_vma (segment->p_paddr, FULL_HEX);
7147 putchar (' ');
7149 if ((unsigned long) segment->p_filesz == segment->p_filesz)
7150 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
7151 else
7153 print_vma (segment->p_filesz, FULL_HEX);
7154 putchar (' ');
7157 if ((unsigned long) segment->p_memsz == segment->p_memsz)
7158 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
7159 else
7161 print_vma (segment->p_memsz, FULL_HEX);
7164 printf (" %c%c%c ",
7165 (segment->p_flags & PF_R ? 'R' : ' '),
7166 (segment->p_flags & PF_W ? 'W' : ' '),
7167 (segment->p_flags & PF_X ? 'E' : ' '));
7169 if ((unsigned long) segment->p_align == segment->p_align)
7170 printf ("%#lx", (unsigned long) segment->p_align);
7171 else
7173 print_vma (segment->p_align, PREFIX_HEX);
7176 else
7178 print_vma (segment->p_offset, FULL_HEX);
7179 putchar (' ');
7180 print_vma (segment->p_vaddr, FULL_HEX);
7181 putchar (' ');
7182 print_vma (segment->p_paddr, FULL_HEX);
7183 printf ("\n ");
7184 print_vma (segment->p_filesz, FULL_HEX);
7185 putchar (' ');
7186 print_vma (segment->p_memsz, FULL_HEX);
7187 printf (" %c%c%c ",
7188 (segment->p_flags & PF_R ? 'R' : ' '),
7189 (segment->p_flags & PF_W ? 'W' : ' '),
7190 (segment->p_flags & PF_X ? 'E' : ' '));
7191 print_vma (segment->p_align, PREFIX_HEX);
7194 putc ('\n', stdout);
7197 switch (segment->p_type)
7199 case PT_LOAD:
7200 #if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
7201 required by the ELF standard, several programs, including the Linux
7202 kernel, make use of non-ordered segments. */
7203 if (previous_load
7204 && previous_load->p_vaddr > segment->p_vaddr)
7205 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
7206 #endif
7207 if (segment->p_memsz < segment->p_filesz)
7208 error (_("the segment's file size is larger than its memory size\n"));
7209 previous_load = segment;
7210 break;
7212 case PT_PHDR:
7213 /* PR 20815 - Verify that the program header is loaded into memory. */
7214 if (i > 0 && previous_load != NULL)
7215 error (_("the PHDR segment must occur before any LOAD segment\n"));
7216 if (filedata->file_header.e_machine != EM_PARISC)
7218 unsigned int j;
7220 for (j = 1; j < filedata->file_header.e_phnum; j++)
7222 Elf_Internal_Phdr *load = filedata->program_headers + j;
7223 if (load->p_type == PT_LOAD
7224 && load->p_offset <= segment->p_offset
7225 && (load->p_offset + load->p_filesz
7226 >= segment->p_offset + segment->p_filesz)
7227 && load->p_vaddr <= segment->p_vaddr
7228 && (load->p_vaddr + load->p_filesz
7229 >= segment->p_vaddr + segment->p_filesz))
7230 break;
7232 if (j == filedata->file_header.e_phnum)
7233 error (_("the PHDR segment is not covered by a LOAD segment\n"));
7235 break;
7237 case PT_DYNAMIC:
7238 if (dynamic_addr)
7239 error (_("more than one dynamic segment\n"));
7241 /* By default, assume that the .dynamic section is the first
7242 section in the DYNAMIC segment. */
7243 dynamic_addr = segment->p_offset;
7244 dynamic_size = segment->p_filesz;
7246 /* Try to locate the .dynamic section. If there is
7247 a section header table, we can easily locate it. */
7248 if (filedata->section_headers != NULL)
7250 Elf_Internal_Shdr * sec;
7252 sec = find_section (filedata, ".dynamic");
7253 if (sec == NULL || sec->sh_size == 0)
7255 /* A corresponding .dynamic section is expected, but on
7256 IA-64/OpenVMS it is OK for it to be missing. */
7257 if (!is_ia64_vms (filedata))
7258 error (_("no .dynamic section in the dynamic segment\n"));
7259 break;
7262 if (sec->sh_type == SHT_NOBITS)
7264 dynamic_addr = 0;
7265 dynamic_size = 0;
7266 break;
7269 dynamic_addr = sec->sh_offset;
7270 dynamic_size = sec->sh_size;
7272 /* The PT_DYNAMIC segment, which is used by the run-time
7273 loader, should exactly match the .dynamic section. */
7274 if (do_checks
7275 && (dynamic_addr != segment->p_offset
7276 || dynamic_size != segment->p_filesz))
7277 warn (_("\
7278 the .dynamic section is not the same as the dynamic segment\n"));
7281 /* PR binutils/17512: Avoid corrupt dynamic section info in the
7282 segment. Check this after matching against the section headers
7283 so we don't warn on debuginfo file (which have NOBITS .dynamic
7284 sections). */
7285 if (dynamic_addr > filedata->file_size
7286 || (dynamic_size > filedata->file_size - dynamic_addr))
7288 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
7289 dynamic_addr = 0;
7290 dynamic_size = 0;
7292 break;
7294 case PT_INTERP:
7295 if (segment->p_offset >= filedata->file_size
7296 || segment->p_filesz > filedata->file_size - segment->p_offset
7297 || segment->p_filesz - 1 >= (size_t) -2
7298 || fseek64 (filedata->handle,
7299 filedata->archive_file_offset + segment->p_offset,
7300 SEEK_SET))
7301 error (_("Unable to find program interpreter name\n"));
7302 else
7304 size_t len = segment->p_filesz;
7305 free (filedata->program_interpreter);
7306 filedata->program_interpreter = xmalloc (len + 1);
7307 len = fread (filedata->program_interpreter, 1, len,
7308 filedata->handle);
7309 filedata->program_interpreter[len] = 0;
7311 if (do_segments)
7312 printf (_(" [Requesting program interpreter: %s]\n"),
7313 filedata->program_interpreter);
7315 break;
7319 if (do_segments
7320 && filedata->section_headers != NULL
7321 && filedata->string_table != NULL)
7323 printf (_("\n Section to Segment mapping:\n"));
7324 printf (_(" Segment Sections...\n"));
7326 for (i = 0; i < filedata->file_header.e_phnum; i++)
7328 unsigned int j;
7329 Elf_Internal_Shdr * section;
7331 segment = filedata->program_headers + i;
7332 section = filedata->section_headers + 1;
7334 printf (" %2.2d ", i);
7336 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
7338 if (!ELF_TBSS_SPECIAL (section, segment)
7339 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
7340 printf ("%s ", printable_section_name (filedata, section));
7343 putc ('\n',stdout);
7347 filedata->dynamic_addr = dynamic_addr;
7348 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
7349 return;
7351 no_headers:
7352 filedata->dynamic_addr = 0;
7353 filedata->dynamic_size = 1;
7357 /* Find the file offset corresponding to VMA by using the program headers. */
7359 static int64_t
7360 offset_from_vma (Filedata * filedata, uint64_t vma, uint64_t size)
7362 Elf_Internal_Phdr * seg;
7364 if (! get_program_headers (filedata))
7366 warn (_("Cannot interpret virtual addresses without program headers.\n"));
7367 return (long) vma;
7370 for (seg = filedata->program_headers;
7371 seg < filedata->program_headers + filedata->file_header.e_phnum;
7372 ++seg)
7374 if (seg->p_type != PT_LOAD)
7375 continue;
7377 if (vma >= (seg->p_vaddr & -seg->p_align)
7378 && vma + size <= seg->p_vaddr + seg->p_filesz)
7379 return vma - seg->p_vaddr + seg->p_offset;
7382 warn (_("Virtual address %#" PRIx64
7383 " not located in any PT_LOAD segment.\n"), vma);
7384 return vma;
7388 /* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
7389 If PROBE is true, this is just a probe and we do not generate any error
7390 messages if the load fails. */
7392 static bool
7393 get_32bit_section_headers (Filedata * filedata, bool probe)
7395 Elf32_External_Shdr * shdrs;
7396 Elf_Internal_Shdr * internal;
7397 unsigned int i;
7398 unsigned int size = filedata->file_header.e_shentsize;
7399 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
7401 /* PR binutils/17531: Cope with unexpected section header sizes. */
7402 if (size == 0 || num == 0)
7403 return false;
7405 /* The section header cannot be at the start of the file - that is
7406 where the ELF file header is located. A file with absolutely no
7407 sections in it will use a shoff of 0. */
7408 if (filedata->file_header.e_shoff == 0)
7409 return false;
7411 if (size < sizeof * shdrs)
7413 if (! probe)
7414 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
7415 return false;
7417 if (!probe && size > sizeof * shdrs)
7418 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
7420 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
7421 size, num,
7422 probe ? NULL : _("section headers"));
7423 if (shdrs == NULL)
7424 return false;
7426 filedata->section_headers = (Elf_Internal_Shdr *)
7427 cmalloc (num, sizeof (Elf_Internal_Shdr));
7428 if (filedata->section_headers == NULL)
7430 if (!probe)
7431 error (_("Out of memory reading %u section headers\n"), num);
7432 free (shdrs);
7433 return false;
7436 for (i = 0, internal = filedata->section_headers;
7437 i < num;
7438 i++, internal++)
7440 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
7441 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
7442 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
7443 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
7444 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
7445 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
7446 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
7447 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
7448 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
7449 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
7450 if (!probe && internal->sh_link > num)
7451 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
7452 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
7453 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
7456 free (shdrs);
7457 return true;
7460 /* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
7462 static bool
7463 get_64bit_section_headers (Filedata * filedata, bool probe)
7465 Elf64_External_Shdr * shdrs;
7466 Elf_Internal_Shdr * internal;
7467 unsigned int i;
7468 unsigned int size = filedata->file_header.e_shentsize;
7469 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
7471 /* PR binutils/17531: Cope with unexpected section header sizes. */
7472 if (size == 0 || num == 0)
7473 return false;
7475 /* The section header cannot be at the start of the file - that is
7476 where the ELF file header is located. A file with absolutely no
7477 sections in it will use a shoff of 0. */
7478 if (filedata->file_header.e_shoff == 0)
7479 return false;
7481 if (size < sizeof * shdrs)
7483 if (! probe)
7484 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
7485 return false;
7488 if (! probe && size > sizeof * shdrs)
7489 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
7491 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
7492 filedata->file_header.e_shoff,
7493 size, num,
7494 probe ? NULL : _("section headers"));
7495 if (shdrs == NULL)
7496 return false;
7498 filedata->section_headers = (Elf_Internal_Shdr *)
7499 cmalloc (num, sizeof (Elf_Internal_Shdr));
7500 if (filedata->section_headers == NULL)
7502 if (! probe)
7503 error (_("Out of memory reading %u section headers\n"), num);
7504 free (shdrs);
7505 return false;
7508 for (i = 0, internal = filedata->section_headers;
7509 i < num;
7510 i++, internal++)
7512 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
7513 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
7514 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
7515 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
7516 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
7517 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
7518 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
7519 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
7520 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
7521 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
7522 if (!probe && internal->sh_link > num)
7523 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
7524 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
7525 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
7528 free (shdrs);
7529 return true;
7532 static bool
7533 get_section_headers (Filedata *filedata, bool probe)
7535 if (filedata->section_headers != NULL)
7536 return true;
7538 if (is_32bit_elf)
7539 return get_32bit_section_headers (filedata, probe);
7540 else
7541 return get_64bit_section_headers (filedata, probe);
7544 static Elf_Internal_Sym *
7545 get_32bit_elf_symbols (Filedata *filedata,
7546 Elf_Internal_Shdr *section,
7547 uint64_t *num_syms_return)
7549 uint64_t number = 0;
7550 Elf32_External_Sym * esyms = NULL;
7551 Elf_External_Sym_Shndx * shndx = NULL;
7552 Elf_Internal_Sym * isyms = NULL;
7553 Elf_Internal_Sym * psym;
7554 unsigned int j;
7555 elf_section_list * entry;
7557 if (section->sh_size == 0)
7559 if (num_syms_return != NULL)
7560 * num_syms_return = 0;
7561 return NULL;
7564 /* Run some sanity checks first. */
7565 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
7567 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
7568 printable_section_name (filedata, section),
7569 section->sh_entsize);
7570 goto exit_point;
7573 if (section->sh_size > filedata->file_size)
7575 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
7576 printable_section_name (filedata, section),
7577 section->sh_size);
7578 goto exit_point;
7581 number = section->sh_size / section->sh_entsize;
7583 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
7585 error (_("Size (%#" PRIx64 ") of section %s "
7586 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7587 section->sh_size,
7588 printable_section_name (filedata, section),
7589 section->sh_entsize);
7590 goto exit_point;
7593 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
7594 section->sh_size, _("symbols"));
7595 if (esyms == NULL)
7596 goto exit_point;
7598 shndx = NULL;
7599 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
7601 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
7602 continue;
7604 if (shndx != NULL)
7606 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7607 free (shndx);
7610 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7611 entry->hdr->sh_offset,
7612 1, entry->hdr->sh_size,
7613 _("symbol table section indices"));
7614 if (shndx == NULL)
7615 goto exit_point;
7617 /* PR17531: file: heap-buffer-overflow */
7618 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7620 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
7621 printable_section_name (filedata, entry->hdr),
7622 entry->hdr->sh_size,
7623 section->sh_size);
7624 goto exit_point;
7628 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
7630 if (isyms == NULL)
7632 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
7633 goto exit_point;
7636 for (j = 0, psym = isyms; j < number; j++, psym++)
7638 psym->st_name = BYTE_GET (esyms[j].st_name);
7639 psym->st_value = BYTE_GET (esyms[j].st_value);
7640 psym->st_size = BYTE_GET (esyms[j].st_size);
7641 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
7642 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
7643 psym->st_shndx
7644 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
7645 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7646 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
7647 psym->st_info = BYTE_GET (esyms[j].st_info);
7648 psym->st_other = BYTE_GET (esyms[j].st_other);
7651 exit_point:
7652 free (shndx);
7653 free (esyms);
7655 if (num_syms_return != NULL)
7656 * num_syms_return = isyms == NULL ? 0 : number;
7658 return isyms;
7661 static Elf_Internal_Sym *
7662 get_64bit_elf_symbols (Filedata *filedata,
7663 Elf_Internal_Shdr *section,
7664 uint64_t *num_syms_return)
7666 uint64_t number = 0;
7667 Elf64_External_Sym * esyms = NULL;
7668 Elf_External_Sym_Shndx * shndx = NULL;
7669 Elf_Internal_Sym * isyms = NULL;
7670 Elf_Internal_Sym * psym;
7671 unsigned int j;
7672 elf_section_list * entry;
7674 if (section->sh_size == 0)
7676 if (num_syms_return != NULL)
7677 * num_syms_return = 0;
7678 return NULL;
7681 /* Run some sanity checks first. */
7682 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
7684 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
7685 printable_section_name (filedata, section),
7686 section->sh_entsize);
7687 goto exit_point;
7690 if (section->sh_size > filedata->file_size)
7692 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
7693 printable_section_name (filedata, section),
7694 section->sh_size);
7695 goto exit_point;
7698 number = section->sh_size / section->sh_entsize;
7700 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
7702 error (_("Size (%#" PRIx64 ") of section %s "
7703 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7704 section->sh_size,
7705 printable_section_name (filedata, section),
7706 section->sh_entsize);
7707 goto exit_point;
7710 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
7711 section->sh_size, _("symbols"));
7712 if (!esyms)
7713 goto exit_point;
7715 shndx = NULL;
7716 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
7718 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
7719 continue;
7721 if (shndx != NULL)
7723 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7724 free (shndx);
7727 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7728 entry->hdr->sh_offset,
7729 1, entry->hdr->sh_size,
7730 _("symbol table section indices"));
7731 if (shndx == NULL)
7732 goto exit_point;
7734 /* PR17531: file: heap-buffer-overflow */
7735 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7737 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
7738 printable_section_name (filedata, entry->hdr),
7739 entry->hdr->sh_size,
7740 section->sh_size);
7741 goto exit_point;
7745 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
7747 if (isyms == NULL)
7749 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
7750 goto exit_point;
7753 for (j = 0, psym = isyms; j < number; j++, psym++)
7755 psym->st_name = BYTE_GET (esyms[j].st_name);
7756 psym->st_info = BYTE_GET (esyms[j].st_info);
7757 psym->st_other = BYTE_GET (esyms[j].st_other);
7758 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
7760 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
7761 psym->st_shndx
7762 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
7763 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7764 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
7766 psym->st_value = BYTE_GET (esyms[j].st_value);
7767 psym->st_size = BYTE_GET (esyms[j].st_size);
7770 exit_point:
7771 free (shndx);
7772 free (esyms);
7774 if (num_syms_return != NULL)
7775 * num_syms_return = isyms == NULL ? 0 : number;
7777 return isyms;
7780 static Elf_Internal_Sym *
7781 get_elf_symbols (Filedata *filedata,
7782 Elf_Internal_Shdr *section,
7783 uint64_t *num_syms_return)
7785 if (is_32bit_elf)
7786 return get_32bit_elf_symbols (filedata, section, num_syms_return);
7787 else
7788 return get_64bit_elf_symbols (filedata, section, num_syms_return);
7791 static const char *
7792 get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
7794 static char buff[1024];
7795 char * p = buff;
7796 unsigned int field_size = is_32bit_elf ? 8 : 16;
7797 signed int sindex;
7798 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
7799 uint64_t os_flags = 0;
7800 uint64_t proc_flags = 0;
7801 uint64_t unknown_flags = 0;
7802 static const struct
7804 const char * str;
7805 unsigned int len;
7807 flags [] =
7809 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
7810 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
7811 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
7812 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
7813 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
7814 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
7815 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
7816 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
7817 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
7818 /* 9 */ { STRING_COMMA_LEN ("TLS") },
7819 /* IA-64 specific. */
7820 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
7821 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
7822 /* IA-64 OpenVMS specific. */
7823 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
7824 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
7825 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
7826 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
7827 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
7828 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
7829 /* Generic. */
7830 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
7831 /* SPARC specific. */
7832 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
7833 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
7834 /* ARM specific. */
7835 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
7836 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
7837 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
7838 /* GNU specific. */
7839 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
7840 /* VLE specific. */
7841 /* 25 */ { STRING_COMMA_LEN ("VLE") },
7842 /* GNU specific. */
7843 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
7846 if (do_section_details)
7847 p += sprintf (p, "[%*.*lx]: ",
7848 field_size, field_size, (unsigned long) sh_flags);
7850 while (sh_flags)
7852 uint64_t flag;
7854 flag = sh_flags & - sh_flags;
7855 sh_flags &= ~ flag;
7857 if (do_section_details)
7859 switch (flag)
7861 case SHF_WRITE: sindex = 0; break;
7862 case SHF_ALLOC: sindex = 1; break;
7863 case SHF_EXECINSTR: sindex = 2; break;
7864 case SHF_MERGE: sindex = 3; break;
7865 case SHF_STRINGS: sindex = 4; break;
7866 case SHF_INFO_LINK: sindex = 5; break;
7867 case SHF_LINK_ORDER: sindex = 6; break;
7868 case SHF_OS_NONCONFORMING: sindex = 7; break;
7869 case SHF_GROUP: sindex = 8; break;
7870 case SHF_TLS: sindex = 9; break;
7871 case SHF_EXCLUDE: sindex = 18; break;
7872 case SHF_COMPRESSED: sindex = 20; break;
7874 default:
7875 sindex = -1;
7876 switch (filedata->file_header.e_machine)
7878 case EM_IA_64:
7879 if (flag == SHF_IA_64_SHORT)
7880 sindex = 10;
7881 else if (flag == SHF_IA_64_NORECOV)
7882 sindex = 11;
7883 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
7884 switch (flag)
7886 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
7887 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
7888 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
7889 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
7890 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
7891 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
7892 default: break;
7894 break;
7896 case EM_386:
7897 case EM_IAMCU:
7898 case EM_X86_64:
7899 case EM_L1OM:
7900 case EM_K1OM:
7901 case EM_OLD_SPARCV9:
7902 case EM_SPARC32PLUS:
7903 case EM_SPARCV9:
7904 case EM_SPARC:
7905 if (flag == SHF_ORDERED)
7906 sindex = 19;
7907 break;
7909 case EM_ARM:
7910 switch (flag)
7912 case SHF_ENTRYSECT: sindex = 21; break;
7913 case SHF_ARM_PURECODE: sindex = 22; break;
7914 case SHF_COMDEF: sindex = 23; break;
7915 default: break;
7917 break;
7918 case EM_PPC:
7919 if (flag == SHF_PPC_VLE)
7920 sindex = 25;
7921 break;
7922 default:
7923 break;
7926 switch (filedata->file_header.e_ident[EI_OSABI])
7928 case ELFOSABI_GNU:
7929 case ELFOSABI_FREEBSD:
7930 if (flag == SHF_GNU_RETAIN)
7931 sindex = 26;
7932 /* Fall through */
7933 case ELFOSABI_NONE:
7934 if (flag == SHF_GNU_MBIND)
7935 /* We should not recognize SHF_GNU_MBIND for
7936 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7937 not set the EI_OSABI header byte. */
7938 sindex = 24;
7939 break;
7940 default:
7941 break;
7943 break;
7946 if (sindex != -1)
7948 if (p != buff + field_size + 4)
7950 if (size < (10 + 2))
7952 warn (_("Internal error: not enough buffer room for section flag info"));
7953 return _("<unknown>");
7955 size -= 2;
7956 *p++ = ',';
7957 *p++ = ' ';
7960 size -= flags [sindex].len;
7961 p = stpcpy (p, flags [sindex].str);
7963 else if (flag & SHF_MASKOS)
7964 os_flags |= flag;
7965 else if (flag & SHF_MASKPROC)
7966 proc_flags |= flag;
7967 else
7968 unknown_flags |= flag;
7970 else
7972 switch (flag)
7974 case SHF_WRITE: *p = 'W'; break;
7975 case SHF_ALLOC: *p = 'A'; break;
7976 case SHF_EXECINSTR: *p = 'X'; break;
7977 case SHF_MERGE: *p = 'M'; break;
7978 case SHF_STRINGS: *p = 'S'; break;
7979 case SHF_INFO_LINK: *p = 'I'; break;
7980 case SHF_LINK_ORDER: *p = 'L'; break;
7981 case SHF_OS_NONCONFORMING: *p = 'O'; break;
7982 case SHF_GROUP: *p = 'G'; break;
7983 case SHF_TLS: *p = 'T'; break;
7984 case SHF_EXCLUDE: *p = 'E'; break;
7985 case SHF_COMPRESSED: *p = 'C'; break;
7987 default:
7988 if ((filedata->file_header.e_machine == EM_X86_64
7989 || filedata->file_header.e_machine == EM_L1OM
7990 || filedata->file_header.e_machine == EM_K1OM)
7991 && flag == SHF_X86_64_LARGE)
7992 *p = 'l';
7993 else if (filedata->file_header.e_machine == EM_ARM
7994 && flag == SHF_ARM_PURECODE)
7995 *p = 'y';
7996 else if (filedata->file_header.e_machine == EM_PPC
7997 && flag == SHF_PPC_VLE)
7998 *p = 'v';
7999 else if (flag & SHF_MASKOS)
8001 switch (filedata->file_header.e_ident[EI_OSABI])
8003 case ELFOSABI_GNU:
8004 case ELFOSABI_FREEBSD:
8005 if (flag == SHF_GNU_RETAIN)
8007 *p = 'R';
8008 break;
8010 /* Fall through */
8011 case ELFOSABI_NONE:
8012 if (flag == SHF_GNU_MBIND)
8014 /* We should not recognize SHF_GNU_MBIND for
8015 ELFOSABI_NONE, but binutils as of 2019-07-23 did
8016 not set the EI_OSABI header byte. */
8017 *p = 'D';
8018 break;
8020 /* Fall through */
8021 default:
8022 *p = 'o';
8023 sh_flags &= ~SHF_MASKOS;
8024 break;
8027 else if (flag & SHF_MASKPROC)
8029 *p = 'p';
8030 sh_flags &= ~ SHF_MASKPROC;
8032 else
8033 *p = 'x';
8034 break;
8036 p++;
8040 if (do_section_details)
8042 if (os_flags)
8044 if (p != buff + field_size + 4)
8046 if (size < 2 + 5 + field_size + 1)
8048 warn (_("Internal error: not enough buffer room for section flag info"));
8049 return _("<unknown>");
8051 size -= 2;
8052 *p++ = ',';
8053 *p++ = ' ';
8055 size -= 5 + field_size;
8056 p += sprintf (p, "OS (%*.*lx)", field_size, field_size,
8057 (unsigned long) os_flags);
8059 if (proc_flags)
8061 if (p != buff + field_size + 4)
8063 if (size < 2 + 7 + field_size + 1)
8065 warn (_("Internal error: not enough buffer room for section flag info"));
8066 return _("<unknown>");
8068 size -= 2;
8069 *p++ = ',';
8070 *p++ = ' ';
8072 size -= 7 + field_size;
8073 p += sprintf (p, "PROC (%*.*lx)", field_size, field_size,
8074 (unsigned long) proc_flags);
8076 if (unknown_flags)
8078 if (p != buff + field_size + 4)
8080 if (size < 2 + 10 + field_size + 1)
8082 warn (_("Internal error: not enough buffer room for section flag info"));
8083 return _("<unknown>");
8085 size -= 2;
8086 *p++ = ',';
8087 *p++ = ' ';
8089 size -= 10 + field_size;
8090 p += sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8091 (unsigned long) unknown_flags);
8095 *p = '\0';
8096 return buff;
8099 static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
8100 get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf,
8101 uint64_t size)
8103 if (is_32bit_elf)
8105 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
8107 if (size < sizeof (* echdr))
8109 error (_("Compressed section is too small even for a compression header\n"));
8110 return 0;
8113 chdr->ch_type = BYTE_GET (echdr->ch_type);
8114 chdr->ch_size = BYTE_GET (echdr->ch_size);
8115 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
8116 return sizeof (*echdr);
8118 else
8120 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
8122 if (size < sizeof (* echdr))
8124 error (_("Compressed section is too small even for a compression header\n"));
8125 return 0;
8128 chdr->ch_type = BYTE_GET (echdr->ch_type);
8129 chdr->ch_size = BYTE_GET (echdr->ch_size);
8130 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
8131 return sizeof (*echdr);
8135 static bool
8136 process_section_headers (Filedata * filedata)
8138 Elf_Internal_Shdr * section;
8139 unsigned int i;
8141 if (filedata->file_header.e_shnum == 0)
8143 /* PR binutils/12467. */
8144 if (filedata->file_header.e_shoff != 0)
8146 warn (_("possibly corrupt ELF file header - it has a non-zero"
8147 " section header offset, but no section headers\n"));
8148 return false;
8150 else if (do_sections)
8151 printf (_("\nThere are no sections in this file.\n"));
8153 return true;
8156 if (do_sections && !do_header)
8158 if (filedata->is_separate && process_links)
8159 printf (_("In linked file '%s': "), filedata->file_name);
8160 if (! filedata->is_separate || process_links)
8161 printf (ngettext ("There is %d section header, "
8162 "starting at offset %#" PRIx64 ":\n",
8163 "There are %d section headers, "
8164 "starting at offset %#" PRIx64 ":\n",
8165 filedata->file_header.e_shnum),
8166 filedata->file_header.e_shnum,
8167 filedata->file_header.e_shoff);
8170 if (!get_section_headers (filedata, false))
8171 return false;
8173 /* Read in the string table, so that we have names to display. */
8174 if (filedata->file_header.e_shstrndx != SHN_UNDEF
8175 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
8177 section = filedata->section_headers + filedata->file_header.e_shstrndx;
8179 if (section->sh_size != 0)
8181 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
8182 1, section->sh_size,
8183 _("string table"));
8185 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
8189 /* Scan the sections for the dynamic symbol table
8190 and dynamic string table and debug sections. */
8191 eh_addr_size = is_32bit_elf ? 4 : 8;
8192 switch (filedata->file_header.e_machine)
8194 case EM_MIPS:
8195 case EM_MIPS_RS3_LE:
8196 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
8197 FDE addresses. However, the ABI also has a semi-official ILP32
8198 variant for which the normal FDE address size rules apply.
8200 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
8201 section, where XX is the size of longs in bits. Unfortunately,
8202 earlier compilers provided no way of distinguishing ILP32 objects
8203 from LP64 objects, so if there's any doubt, we should assume that
8204 the official LP64 form is being used. */
8205 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == EF_MIPS_ABI_EABI64
8206 && find_section (filedata, ".gcc_compiled_long32") == NULL)
8207 eh_addr_size = 8;
8208 break;
8210 case EM_H8_300:
8211 case EM_H8_300H:
8212 switch (filedata->file_header.e_flags & EF_H8_MACH)
8214 case E_H8_MACH_H8300:
8215 case E_H8_MACH_H8300HN:
8216 case E_H8_MACH_H8300SN:
8217 case E_H8_MACH_H8300SXN:
8218 eh_addr_size = 2;
8219 break;
8220 case E_H8_MACH_H8300H:
8221 case E_H8_MACH_H8300S:
8222 case E_H8_MACH_H8300SX:
8223 eh_addr_size = 4;
8224 break;
8226 break;
8228 case EM_M32C_OLD:
8229 case EM_M32C:
8230 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
8232 case EF_M32C_CPU_M16C:
8233 eh_addr_size = 2;
8234 break;
8236 break;
8239 #define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
8240 do \
8242 uint64_t expected_entsize = is_32bit_elf ? size32 : size64; \
8243 if (section->sh_entsize != expected_entsize) \
8245 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
8246 i, section->sh_entsize); \
8247 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
8248 expected_entsize); \
8249 section->sh_entsize = expected_entsize; \
8252 while (0)
8254 #define CHECK_ENTSIZE(section, i, type) \
8255 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
8256 sizeof (Elf64_External_##type))
8258 for (i = 0, section = filedata->section_headers;
8259 i < filedata->file_header.e_shnum;
8260 i++, section++)
8262 const char *name = printable_section_name (filedata, section);
8264 /* Run some sanity checks on the headers and
8265 possibly fill in some file data as well. */
8266 switch (section->sh_type)
8268 case SHT_DYNSYM:
8269 if (filedata->dynamic_symbols != NULL)
8271 error (_("File contains multiple dynamic symbol tables\n"));
8272 continue;
8275 CHECK_ENTSIZE (section, i, Sym);
8276 filedata->dynamic_symbols
8277 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8278 filedata->dynamic_symtab_section = section;
8279 break;
8281 case SHT_STRTAB:
8282 if (streq (name, ".dynstr"))
8284 if (filedata->dynamic_strings != NULL)
8286 error (_("File contains multiple dynamic string tables\n"));
8287 continue;
8290 filedata->dynamic_strings
8291 = (char *) get_data (NULL, filedata, section->sh_offset,
8292 1, section->sh_size, _("dynamic strings"));
8293 filedata->dynamic_strings_length
8294 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8295 filedata->dynamic_strtab_section = section;
8297 break;
8299 case SHT_SYMTAB_SHNDX:
8301 elf_section_list * entry = xmalloc (sizeof * entry);
8303 entry->hdr = section;
8304 entry->next = filedata->symtab_shndx_list;
8305 filedata->symtab_shndx_list = entry;
8307 break;
8309 case SHT_SYMTAB:
8310 CHECK_ENTSIZE (section, i, Sym);
8311 break;
8313 case SHT_GROUP:
8314 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
8315 break;
8317 case SHT_REL:
8318 CHECK_ENTSIZE (section, i, Rel);
8319 if (do_checks && section->sh_size == 0)
8320 warn (_("Section '%s': zero-sized relocation section\n"), name);
8321 break;
8323 case SHT_RELA:
8324 CHECK_ENTSIZE (section, i, Rela);
8325 if (do_checks && section->sh_size == 0)
8326 warn (_("Section '%s': zero-sized relocation section\n"), name);
8327 break;
8329 case SHT_RELR:
8330 CHECK_ENTSIZE (section, i, Relr);
8331 break;
8333 case SHT_NOTE:
8334 case SHT_PROGBITS:
8335 /* Having a zero sized section is not illegal according to the
8336 ELF standard, but it might be an indication that something
8337 is wrong. So issue a warning if we are running in lint mode. */
8338 if (do_checks && section->sh_size == 0)
8339 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
8340 break;
8342 default:
8343 break;
8346 if ((do_debugging || do_debug_info || do_debug_abbrevs
8347 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
8348 || do_debug_aranges || do_debug_frames || do_debug_macinfo
8349 || do_debug_str || do_debug_str_offsets || do_debug_loc
8350 || do_debug_ranges
8351 || do_debug_addr || do_debug_cu_index || do_debug_links)
8352 && (startswith (name, ".debug_")
8353 || startswith (name, ".zdebug_")))
8355 if (name[1] == 'z')
8356 name += sizeof (".zdebug_") - 1;
8357 else
8358 name += sizeof (".debug_") - 1;
8360 if (do_debugging
8361 || (do_debug_info && startswith (name, "info"))
8362 || (do_debug_info && startswith (name, "types"))
8363 || (do_debug_abbrevs && startswith (name, "abbrev"))
8364 || (do_debug_lines && strcmp (name, "line") == 0)
8365 || (do_debug_lines && startswith (name, "line."))
8366 || (do_debug_pubnames && startswith (name, "pubnames"))
8367 || (do_debug_pubtypes && startswith (name, "pubtypes"))
8368 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
8369 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
8370 || (do_debug_aranges && startswith (name, "aranges"))
8371 || (do_debug_ranges && startswith (name, "ranges"))
8372 || (do_debug_ranges && startswith (name, "rnglists"))
8373 || (do_debug_frames && startswith (name, "frame"))
8374 || (do_debug_macinfo && startswith (name, "macinfo"))
8375 || (do_debug_macinfo && startswith (name, "macro"))
8376 || (do_debug_str && startswith (name, "str"))
8377 || (do_debug_links && startswith (name, "sup"))
8378 || (do_debug_str_offsets && startswith (name, "str_offsets"))
8379 || (do_debug_loc && startswith (name, "loc"))
8380 || (do_debug_loc && startswith (name, "loclists"))
8381 || (do_debug_addr && startswith (name, "addr"))
8382 || (do_debug_cu_index && startswith (name, "cu_index"))
8383 || (do_debug_cu_index && startswith (name, "tu_index"))
8385 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
8387 /* Linkonce section to be combined with .debug_info at link time. */
8388 else if ((do_debugging || do_debug_info)
8389 && startswith (name, ".gnu.linkonce.wi."))
8390 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
8391 else if (do_debug_frames && streq (name, ".eh_frame"))
8392 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
8393 else if (do_debug_frames && streq (name, ".eh_frame_hdr"))
8394 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
8395 else if (do_gdb_index && (streq (name, ".gdb_index")
8396 || streq (name, ".debug_names")))
8397 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
8398 /* Trace sections for Itanium VMS. */
8399 else if ((do_debugging || do_trace_info || do_trace_abbrevs
8400 || do_trace_aranges)
8401 && startswith (name, ".trace_"))
8403 name += sizeof (".trace_") - 1;
8405 if (do_debugging
8406 || (do_trace_info && streq (name, "info"))
8407 || (do_trace_abbrevs && streq (name, "abbrev"))
8408 || (do_trace_aranges && streq (name, "aranges"))
8410 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
8412 else if ((do_debugging || do_debug_links)
8413 && (startswith (name, ".gnu_debuglink")
8414 || startswith (name, ".gnu_debugaltlink")))
8415 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
8418 if (! do_sections)
8419 return true;
8421 if (filedata->is_separate && ! process_links)
8422 return true;
8424 if (filedata->is_separate)
8425 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
8426 else if (filedata->file_header.e_shnum > 1)
8427 printf (_("\nSection Headers:\n"));
8428 else
8429 printf (_("\nSection Header:\n"));
8431 if (is_32bit_elf)
8433 if (do_section_details)
8435 printf (_(" [Nr] Name\n"));
8436 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
8438 else
8439 printf
8440 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
8442 else if (do_wide)
8444 if (do_section_details)
8446 printf (_(" [Nr] Name\n"));
8447 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
8449 else
8450 printf
8451 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
8453 else
8455 if (do_section_details)
8457 printf (_(" [Nr] Name\n"));
8458 printf (_(" Type Address Offset Link\n"));
8459 printf (_(" Size EntSize Info Align\n"));
8461 else
8463 printf (_(" [Nr] Name Type Address Offset\n"));
8464 printf (_(" Size EntSize Flags Link Info Align\n"));
8468 if (do_section_details)
8469 printf (_(" Flags\n"));
8471 for (i = 0, section = filedata->section_headers;
8472 i < filedata->file_header.e_shnum;
8473 i++, section++)
8475 /* Run some sanity checks on the section header. */
8477 /* Check the sh_link field. */
8478 switch (section->sh_type)
8480 case SHT_REL:
8481 case SHT_RELR:
8482 case SHT_RELA:
8483 if (section->sh_link == 0
8484 && (filedata->file_header.e_type == ET_EXEC
8485 || filedata->file_header.e_type == ET_DYN))
8486 /* A dynamic relocation section where all entries use a
8487 zero symbol index need not specify a symtab section. */
8488 break;
8489 /* Fall through. */
8490 case SHT_SYMTAB_SHNDX:
8491 case SHT_GROUP:
8492 case SHT_HASH:
8493 case SHT_GNU_HASH:
8494 case SHT_GNU_versym:
8495 if (section->sh_link == 0
8496 || section->sh_link >= filedata->file_header.e_shnum
8497 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
8498 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
8499 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
8500 i, section->sh_link);
8501 break;
8503 case SHT_DYNAMIC:
8504 case SHT_SYMTAB:
8505 case SHT_DYNSYM:
8506 case SHT_GNU_verneed:
8507 case SHT_GNU_verdef:
8508 case SHT_GNU_LIBLIST:
8509 if (section->sh_link == 0
8510 || section->sh_link >= filedata->file_header.e_shnum
8511 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
8512 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
8513 i, section->sh_link);
8514 break;
8516 case SHT_INIT_ARRAY:
8517 case SHT_FINI_ARRAY:
8518 case SHT_PREINIT_ARRAY:
8519 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
8520 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
8521 i, section->sh_link);
8522 break;
8524 default:
8525 /* FIXME: Add support for target specific section types. */
8526 #if 0 /* Currently we do not check other section types as there are too
8527 many special cases. Stab sections for example have a type
8528 of SHT_PROGBITS but an sh_link field that links to the .stabstr
8529 section. */
8530 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
8531 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
8532 i, section->sh_link);
8533 #endif
8534 break;
8537 /* Check the sh_info field. */
8538 switch (section->sh_type)
8540 case SHT_REL:
8541 case SHT_RELA:
8542 if (section->sh_info == 0
8543 && (filedata->file_header.e_type == ET_EXEC
8544 || filedata->file_header.e_type == ET_DYN))
8545 /* Dynamic relocations apply to segments, so they do not
8546 need to specify the section they relocate. */
8547 break;
8548 if (section->sh_info == 0
8549 || section->sh_info >= filedata->file_header.e_shnum
8550 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
8551 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
8552 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
8553 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
8554 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
8555 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
8556 /* FIXME: Are other section types valid ? */
8557 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
8558 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
8559 i, section->sh_info);
8560 break;
8562 case SHT_DYNAMIC:
8563 case SHT_HASH:
8564 case SHT_SYMTAB_SHNDX:
8565 case SHT_INIT_ARRAY:
8566 case SHT_FINI_ARRAY:
8567 case SHT_PREINIT_ARRAY:
8568 if (section->sh_info != 0)
8569 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
8570 i, section->sh_info);
8571 break;
8573 case SHT_GROUP:
8574 case SHT_SYMTAB:
8575 case SHT_DYNSYM:
8576 /* A symbol index - we assume that it is valid. */
8577 break;
8579 default:
8580 /* FIXME: Add support for target specific section types. */
8581 if (section->sh_type == SHT_NOBITS)
8582 /* NOBITS section headers with non-zero sh_info fields can be
8583 created when a binary is stripped of everything but its debug
8584 information. The stripped sections have their headers
8585 preserved but their types set to SHT_NOBITS. So do not check
8586 this type of section. */
8588 else if (section->sh_flags & SHF_INFO_LINK)
8590 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
8591 warn (_("[%2u]: Expected link to another section in info field"), i);
8593 else if (section->sh_type < SHT_LOOS
8594 && (section->sh_flags & SHF_GNU_MBIND) == 0
8595 && section->sh_info != 0)
8596 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
8597 i, section->sh_info);
8598 break;
8601 /* Check the sh_size field. */
8602 if (section->sh_size > filedata->file_size
8603 && section->sh_type != SHT_NOBITS
8604 && section->sh_type != SHT_NULL
8605 && section->sh_type < SHT_LOOS)
8606 warn (_("Size of section %u is larger than the entire file!\n"), i);
8608 printf (" [%2u] ", i);
8609 if (do_section_details)
8610 printf ("%s\n ", printable_section_name (filedata, section));
8611 else
8612 print_symbol_name (-17, printable_section_name (filedata, section));
8614 printf (do_wide ? " %-15s " : " %-15.15s ",
8615 get_section_type_name (filedata, section->sh_type));
8617 if (is_32bit_elf)
8619 const char * link_too_big = NULL;
8621 print_vma (section->sh_addr, LONG_HEX);
8623 printf ( " %6.6lx %6.6lx %2.2lx",
8624 (unsigned long) section->sh_offset,
8625 (unsigned long) section->sh_size,
8626 (unsigned long) section->sh_entsize);
8628 if (do_section_details)
8629 fputs (" ", stdout);
8630 else
8631 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
8633 if (section->sh_link >= filedata->file_header.e_shnum)
8635 link_too_big = "";
8636 /* The sh_link value is out of range. Normally this indicates
8637 an error but it can have special values in Solaris binaries. */
8638 switch (filedata->file_header.e_machine)
8640 case EM_386:
8641 case EM_IAMCU:
8642 case EM_X86_64:
8643 case EM_L1OM:
8644 case EM_K1OM:
8645 case EM_OLD_SPARCV9:
8646 case EM_SPARC32PLUS:
8647 case EM_SPARCV9:
8648 case EM_SPARC:
8649 if (section->sh_link == (SHN_BEFORE & 0xffff))
8650 link_too_big = "BEFORE";
8651 else if (section->sh_link == (SHN_AFTER & 0xffff))
8652 link_too_big = "AFTER";
8653 break;
8654 default:
8655 break;
8659 if (do_section_details)
8661 if (link_too_big != NULL && * link_too_big)
8662 printf ("<%s> ", link_too_big);
8663 else
8664 printf ("%2u ", section->sh_link);
8665 printf ("%3u %2lu\n", section->sh_info,
8666 (unsigned long) section->sh_addralign);
8668 else
8669 printf ("%2u %3u %2lu\n",
8670 section->sh_link,
8671 section->sh_info,
8672 (unsigned long) section->sh_addralign);
8674 if (link_too_big && ! * link_too_big)
8675 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
8676 i, section->sh_link);
8678 else if (do_wide)
8680 print_vma (section->sh_addr, LONG_HEX);
8682 if ((long) section->sh_offset == section->sh_offset)
8683 printf (" %6.6lx", (unsigned long) section->sh_offset);
8684 else
8686 putchar (' ');
8687 print_vma (section->sh_offset, LONG_HEX);
8690 if ((unsigned long) section->sh_size == section->sh_size)
8691 printf (" %6.6lx", (unsigned long) section->sh_size);
8692 else
8694 putchar (' ');
8695 print_vma (section->sh_size, LONG_HEX);
8698 if ((unsigned long) section->sh_entsize == section->sh_entsize)
8699 printf (" %2.2lx", (unsigned long) section->sh_entsize);
8700 else
8702 putchar (' ');
8703 print_vma (section->sh_entsize, LONG_HEX);
8706 if (do_section_details)
8707 fputs (" ", stdout);
8708 else
8709 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
8711 printf ("%2u %3u ", section->sh_link, section->sh_info);
8713 if ((unsigned long) section->sh_addralign == section->sh_addralign)
8714 printf ("%2lu\n", (unsigned long) section->sh_addralign);
8715 else
8717 print_vma (section->sh_addralign, DEC);
8718 putchar ('\n');
8721 else if (do_section_details)
8723 putchar (' ');
8724 print_vma (section->sh_addr, LONG_HEX);
8725 if ((long) section->sh_offset == section->sh_offset)
8726 printf (" %16.16lx", (unsigned long) section->sh_offset);
8727 else
8729 printf (" ");
8730 print_vma (section->sh_offset, LONG_HEX);
8732 printf (" %u\n ", section->sh_link);
8733 print_vma (section->sh_size, LONG_HEX);
8734 putchar (' ');
8735 print_vma (section->sh_entsize, LONG_HEX);
8737 printf (" %-16u %lu\n",
8738 section->sh_info,
8739 (unsigned long) section->sh_addralign);
8741 else
8743 putchar (' ');
8744 print_vma (section->sh_addr, LONG_HEX);
8745 if ((long) section->sh_offset == section->sh_offset)
8746 printf (" %8.8lx", (unsigned long) section->sh_offset);
8747 else
8749 printf (" ");
8750 print_vma (section->sh_offset, LONG_HEX);
8752 printf ("\n ");
8753 print_vma (section->sh_size, LONG_HEX);
8754 printf (" ");
8755 print_vma (section->sh_entsize, LONG_HEX);
8757 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
8759 printf (" %2u %3u %lu\n",
8760 section->sh_link,
8761 section->sh_info,
8762 (unsigned long) section->sh_addralign);
8765 if (do_section_details)
8767 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
8768 if ((section->sh_flags & SHF_COMPRESSED) != 0)
8770 /* Minimum section size is 12 bytes for 32-bit compression
8771 header + 12 bytes for compressed data header. */
8772 unsigned char buf[24];
8774 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
8775 if (get_data (&buf, filedata, section->sh_offset, 1,
8776 sizeof (buf), _("compression header")))
8778 Elf_Internal_Chdr chdr;
8780 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
8781 printf (_(" [<corrupt>]\n"));
8782 else
8784 if (chdr.ch_type == ch_compress_zlib)
8785 printf (" ZLIB, ");
8786 else if (chdr.ch_type == ch_compress_zstd)
8787 printf (" ZSTD, ");
8788 else
8789 printf (_(" [<unknown>: 0x%x], "),
8790 chdr.ch_type);
8791 print_vma (chdr.ch_size, LONG_HEX);
8792 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
8799 if (!do_section_details)
8801 /* The ordering of the letters shown here matches the ordering of the
8802 corresponding SHF_xxx values, and hence the order in which these
8803 letters will be displayed to the user. */
8804 printf (_("Key to Flags:\n\
8805 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
8806 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
8807 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
8808 switch (filedata->file_header.e_ident[EI_OSABI])
8810 case ELFOSABI_GNU:
8811 case ELFOSABI_FREEBSD:
8812 printf (_("R (retain), "));
8813 /* Fall through */
8814 case ELFOSABI_NONE:
8815 printf (_("D (mbind), "));
8816 break;
8817 default:
8818 break;
8820 if (filedata->file_header.e_machine == EM_X86_64
8821 || filedata->file_header.e_machine == EM_L1OM
8822 || filedata->file_header.e_machine == EM_K1OM)
8823 printf (_("l (large), "));
8824 else if (filedata->file_header.e_machine == EM_ARM)
8825 printf (_("y (purecode), "));
8826 else if (filedata->file_header.e_machine == EM_PPC)
8827 printf (_("v (VLE), "));
8828 printf ("p (processor specific)\n");
8831 return true;
8834 static bool
8835 get_symtab (Filedata * filedata,
8836 Elf_Internal_Shdr * symsec,
8837 Elf_Internal_Sym ** symtab,
8838 uint64_t * nsyms,
8839 char ** strtab,
8840 uint64_t * strtablen)
8842 *strtab = NULL;
8843 *strtablen = 0;
8844 *symtab = get_elf_symbols (filedata, symsec, nsyms);
8846 if (*symtab == NULL)
8847 return false;
8849 if (symsec->sh_link != 0)
8851 Elf_Internal_Shdr *strsec;
8853 if (symsec->sh_link >= filedata->file_header.e_shnum)
8855 error (_("Bad sh_link in symbol table section\n"));
8856 free (*symtab);
8857 *symtab = NULL;
8858 *nsyms = 0;
8859 return false;
8862 strsec = filedata->section_headers + symsec->sh_link;
8864 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
8865 1, strsec->sh_size, _("string table"));
8866 if (*strtab == NULL)
8868 free (*symtab);
8869 *symtab = NULL;
8870 *nsyms = 0;
8871 return false;
8873 *strtablen = strsec->sh_size;
8875 return true;
8878 static const char *
8879 get_group_flags (unsigned int flags)
8881 static char buff[128];
8883 if (flags == 0)
8884 return "";
8885 else if (flags == GRP_COMDAT)
8886 return "COMDAT ";
8888 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
8889 flags,
8890 flags & GRP_MASKOS ? _("<OS specific>") : "",
8891 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
8892 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
8893 ? _("<unknown>") : ""));
8895 return buff;
8898 static bool
8899 process_section_groups (Filedata * filedata)
8901 Elf_Internal_Shdr * section;
8902 unsigned int i;
8903 struct group * group;
8904 Elf_Internal_Shdr * symtab_sec;
8905 Elf_Internal_Shdr * strtab_sec;
8906 Elf_Internal_Sym * symtab;
8907 uint64_t num_syms;
8908 char * strtab;
8909 size_t strtab_size;
8911 /* Don't process section groups unless needed. */
8912 if (!do_unwind && !do_section_groups)
8913 return true;
8915 if (filedata->file_header.e_shnum == 0)
8917 if (do_section_groups)
8919 if (filedata->is_separate)
8920 printf (_("\nThere are no sections group in linked file '%s'.\n"),
8921 filedata->file_name);
8922 else
8923 printf (_("\nThere are no section groups in this file.\n"));
8925 return true;
8928 if (filedata->section_headers == NULL)
8930 error (_("Section headers are not available!\n"));
8931 /* PR 13622: This can happen with a corrupt ELF header. */
8932 return false;
8935 filedata->section_headers_groups
8936 = (struct group **) calloc (filedata->file_header.e_shnum,
8937 sizeof (struct group *));
8939 if (filedata->section_headers_groups == NULL)
8941 error (_("Out of memory reading %u section group headers\n"),
8942 filedata->file_header.e_shnum);
8943 return false;
8946 /* Scan the sections for the group section. */
8947 filedata->group_count = 0;
8948 for (i = 0, section = filedata->section_headers;
8949 i < filedata->file_header.e_shnum;
8950 i++, section++)
8951 if (section->sh_type == SHT_GROUP)
8952 filedata->group_count++;
8954 if (filedata->group_count == 0)
8956 if (do_section_groups)
8958 if (filedata->is_separate)
8959 printf (_("\nThere are no section groups in linked file '%s'.\n"),
8960 filedata->file_name);
8961 else
8962 printf (_("\nThere are no section groups in this file.\n"));
8965 return true;
8968 filedata->section_groups = (struct group *) calloc (filedata->group_count,
8969 sizeof (struct group));
8971 if (filedata->section_groups == NULL)
8973 error (_("Out of memory reading %zu groups\n"), filedata->group_count);
8974 return false;
8977 symtab_sec = NULL;
8978 strtab_sec = NULL;
8979 symtab = NULL;
8980 num_syms = 0;
8981 strtab = NULL;
8982 strtab_size = 0;
8984 if (filedata->is_separate)
8985 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
8987 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
8988 i < filedata->file_header.e_shnum;
8989 i++, section++)
8991 if (section->sh_type == SHT_GROUP)
8993 const char * name = printable_section_name (filedata, section);
8994 const char * group_name;
8995 unsigned char * start;
8996 unsigned char * indices;
8997 unsigned int entry, j, size;
8998 Elf_Internal_Shdr * sec;
8999 Elf_Internal_Sym * sym;
9001 /* Get the symbol table. */
9002 if (section->sh_link >= filedata->file_header.e_shnum
9003 || ((sec = filedata->section_headers + section->sh_link)->sh_type
9004 != SHT_SYMTAB))
9006 error (_("Bad sh_link in group section `%s'\n"), name);
9007 continue;
9010 if (symtab_sec != sec)
9012 symtab_sec = sec;
9013 free (symtab);
9014 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
9017 if (symtab == NULL)
9019 error (_("Corrupt header in group section `%s'\n"), name);
9020 continue;
9023 if (section->sh_info >= num_syms)
9025 error (_("Bad sh_info in group section `%s'\n"), name);
9026 continue;
9029 sym = symtab + section->sh_info;
9031 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
9033 if (sym->st_shndx == 0
9034 || sym->st_shndx >= filedata->file_header.e_shnum)
9036 error (_("Bad sh_info in group section `%s'\n"), name);
9037 continue;
9040 group_name = printable_section_name (filedata,
9041 filedata->section_headers
9042 + sym->st_shndx);
9043 strtab_sec = NULL;
9044 free (strtab);
9045 strtab = NULL;
9046 strtab_size = 0;
9048 else
9050 /* Get the string table. */
9051 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
9053 strtab_sec = NULL;
9054 free (strtab);
9055 strtab = NULL;
9056 strtab_size = 0;
9058 else if (strtab_sec
9059 != (sec = filedata->section_headers + symtab_sec->sh_link))
9061 strtab_sec = sec;
9062 free (strtab);
9064 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
9065 1, strtab_sec->sh_size,
9066 _("string table"));
9067 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
9069 group_name = sym->st_name < strtab_size
9070 ? strtab + sym->st_name : _("<corrupt>");
9073 /* PR 17531: file: loop. */
9074 if (section->sh_entsize > section->sh_size)
9076 error (_("Section %s has sh_entsize (%#" PRIx64 ")"
9077 " which is larger than its size (%#" PRIx64 ")\n"),
9078 printable_section_name (filedata, section),
9079 section->sh_entsize,
9080 section->sh_size);
9081 continue;
9084 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
9085 1, section->sh_size,
9086 _("section data"));
9087 if (start == NULL)
9088 continue;
9090 indices = start;
9091 size = (section->sh_size / section->sh_entsize) - 1;
9092 entry = byte_get (indices, 4);
9093 indices += 4;
9095 if (do_section_groups)
9097 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
9098 get_group_flags (entry), i, name, group_name, size);
9100 printf (_(" [Index] Name\n"));
9103 group->group_index = i;
9105 for (j = 0; j < size; j++)
9107 struct group_list * g;
9109 entry = byte_get (indices, 4);
9110 indices += 4;
9112 if (entry >= filedata->file_header.e_shnum)
9114 static unsigned num_group_errors = 0;
9116 if (num_group_errors ++ < 10)
9118 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
9119 entry, i, filedata->file_header.e_shnum - 1);
9120 if (num_group_errors == 10)
9121 warn (_("Further error messages about overlarge group section indices suppressed\n"));
9123 continue;
9126 if (filedata->section_headers_groups [entry] != NULL)
9128 if (entry)
9130 static unsigned num_errs = 0;
9132 if (num_errs ++ < 10)
9134 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
9135 entry, i,
9136 filedata->section_headers_groups [entry]->group_index);
9137 if (num_errs == 10)
9138 warn (_("Further error messages about already contained group sections suppressed\n"));
9140 continue;
9142 else
9144 /* Intel C/C++ compiler may put section 0 in a
9145 section group. We just warn it the first time
9146 and ignore it afterwards. */
9147 static bool warned = false;
9148 if (!warned)
9150 error (_("section 0 in group section [%5u]\n"),
9151 filedata->section_headers_groups [entry]->group_index);
9152 warned = true;
9157 filedata->section_headers_groups [entry] = group;
9159 if (do_section_groups)
9161 sec = filedata->section_headers + entry;
9162 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
9165 g = (struct group_list *) xmalloc (sizeof (struct group_list));
9166 g->section_index = entry;
9167 g->next = group->root;
9168 group->root = g;
9171 free (start);
9173 group++;
9177 free (symtab);
9178 free (strtab);
9179 return true;
9182 /* Data used to display dynamic fixups. */
9184 struct ia64_vms_dynfixup
9186 uint64_t needed_ident; /* Library ident number. */
9187 uint64_t needed; /* Index in the dstrtab of the library name. */
9188 uint64_t fixup_needed; /* Index of the library. */
9189 uint64_t fixup_rela_cnt; /* Number of fixups. */
9190 uint64_t fixup_rela_off; /* Fixups offset in the dynamic segment. */
9193 /* Data used to display dynamic relocations. */
9195 struct ia64_vms_dynimgrela
9197 uint64_t img_rela_cnt; /* Number of relocations. */
9198 uint64_t img_rela_off; /* Reloc offset in the dynamic segment. */
9201 /* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
9202 library). */
9204 static bool
9205 dump_ia64_vms_dynamic_fixups (Filedata * filedata,
9206 struct ia64_vms_dynfixup * fixup,
9207 const char * strtab,
9208 unsigned int strtab_sz)
9210 Elf64_External_VMS_IMAGE_FIXUP * imfs;
9211 size_t i;
9212 const char * lib_name;
9214 imfs = get_data (NULL, filedata,
9215 filedata->dynamic_addr + fixup->fixup_rela_off,
9216 sizeof (*imfs), fixup->fixup_rela_cnt,
9217 _("dynamic section image fixups"));
9218 if (!imfs)
9219 return false;
9221 if (fixup->needed < strtab_sz)
9222 lib_name = strtab + fixup->needed;
9223 else
9225 warn (_("corrupt library name index of %#" PRIx64
9226 " found in dynamic entry"), fixup->needed);
9227 lib_name = "???";
9230 printf (_("\nImage fixups for needed library #%" PRId64
9231 ": %s - ident: %" PRIx64 "\n"),
9232 fixup->fixup_needed, lib_name, fixup->needed_ident);
9233 printf
9234 (_("Seg Offset Type SymVec DataType\n"));
9236 for (i = 0; i < (size_t) fixup->fixup_rela_cnt; i++)
9238 unsigned int type;
9239 const char *rtype;
9241 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
9242 printf ("%016" PRIx64 " ", BYTE_GET (imfs [i].fixup_offset));
9243 type = BYTE_GET (imfs [i].type);
9244 rtype = elf_ia64_reloc_type (type);
9245 if (rtype == NULL)
9246 printf ("0x%08x ", type);
9247 else
9248 printf ("%-32s ", rtype);
9249 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
9250 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
9253 free (imfs);
9254 return true;
9257 /* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
9259 static bool
9260 dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
9262 Elf64_External_VMS_IMAGE_RELA *imrs;
9263 size_t i;
9265 imrs = get_data (NULL, filedata,
9266 filedata->dynamic_addr + imgrela->img_rela_off,
9267 sizeof (*imrs), imgrela->img_rela_cnt,
9268 _("dynamic section image relocations"));
9269 if (!imrs)
9270 return false;
9272 printf (_("\nImage relocs\n"));
9273 printf
9274 (_("Seg Offset Type Addend Seg Sym Off\n"));
9276 for (i = 0; i < (size_t) imgrela->img_rela_cnt; i++)
9278 unsigned int type;
9279 const char *rtype;
9281 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
9282 printf ("%08" PRIx64 " ", BYTE_GET (imrs [i].rela_offset));
9283 type = BYTE_GET (imrs [i].type);
9284 rtype = elf_ia64_reloc_type (type);
9285 if (rtype == NULL)
9286 printf ("0x%08x ", type);
9287 else
9288 printf ("%-31s ", rtype);
9289 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
9290 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
9291 printf ("%08" PRIx64 "\n", BYTE_GET (imrs [i].sym_offset));
9294 free (imrs);
9295 return true;
9298 /* Display IA-64 OpenVMS dynamic relocations and fixups. */
9300 static bool
9301 process_ia64_vms_dynamic_relocs (Filedata * filedata)
9303 struct ia64_vms_dynfixup fixup;
9304 struct ia64_vms_dynimgrela imgrela;
9305 Elf_Internal_Dyn *entry;
9306 uint64_t strtab_off = 0;
9307 uint64_t strtab_sz = 0;
9308 char *strtab = NULL;
9309 bool res = true;
9311 memset (&fixup, 0, sizeof (fixup));
9312 memset (&imgrela, 0, sizeof (imgrela));
9314 /* Note: the order of the entries is specified by the OpenVMS specs. */
9315 for (entry = filedata->dynamic_section;
9316 entry < filedata->dynamic_section + filedata->dynamic_nent;
9317 entry++)
9319 switch (entry->d_tag)
9321 case DT_IA_64_VMS_STRTAB_OFFSET:
9322 strtab_off = entry->d_un.d_val;
9323 break;
9324 case DT_STRSZ:
9325 strtab_sz = entry->d_un.d_val;
9326 if (strtab == NULL)
9327 strtab = get_data (NULL, filedata,
9328 filedata->dynamic_addr + strtab_off,
9329 1, strtab_sz, _("dynamic string section"));
9330 if (strtab == NULL)
9331 strtab_sz = 0;
9332 break;
9334 case DT_IA_64_VMS_NEEDED_IDENT:
9335 fixup.needed_ident = entry->d_un.d_val;
9336 break;
9337 case DT_NEEDED:
9338 fixup.needed = entry->d_un.d_val;
9339 break;
9340 case DT_IA_64_VMS_FIXUP_NEEDED:
9341 fixup.fixup_needed = entry->d_un.d_val;
9342 break;
9343 case DT_IA_64_VMS_FIXUP_RELA_CNT:
9344 fixup.fixup_rela_cnt = entry->d_un.d_val;
9345 break;
9346 case DT_IA_64_VMS_FIXUP_RELA_OFF:
9347 fixup.fixup_rela_off = entry->d_un.d_val;
9348 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
9349 res = false;
9350 break;
9351 case DT_IA_64_VMS_IMG_RELA_CNT:
9352 imgrela.img_rela_cnt = entry->d_un.d_val;
9353 break;
9354 case DT_IA_64_VMS_IMG_RELA_OFF:
9355 imgrela.img_rela_off = entry->d_un.d_val;
9356 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
9357 res = false;
9358 break;
9360 default:
9361 break;
9365 free (strtab);
9367 return res;
9370 static struct
9372 const char * name;
9373 int reloc;
9374 int size;
9375 relocation_type rel_type;
9377 dynamic_relocations [] =
9379 { "REL", DT_REL, DT_RELSZ, reltype_rel },
9380 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
9381 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
9382 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
9385 static relocation_type
9386 rel_type_from_sh_type (unsigned int sh_type)
9388 switch (sh_type)
9390 case SHT_RELA: return reltype_rela;
9391 case SHT_REL: return reltype_rel;
9392 case SHT_RELR: return reltype_relr;
9393 default: return reltype_unknown;
9397 static bool
9398 display_relocations (Elf_Internal_Shdr * section,
9399 Filedata * filedata)
9401 relocation_type rel_type = rel_type_from_sh_type (section->sh_type);
9403 if (rel_type == reltype_unknown)
9404 return false;
9406 uint64_t rel_size = section->sh_size;
9408 if (rel_size == 0)
9409 return false;
9411 if (filedata->is_separate)
9412 printf (_("\nIn linked file '%s' relocation section "),
9413 filedata->file_name);
9414 else
9415 printf (_("\nRelocation section "));
9417 if (filedata->string_table == NULL)
9418 printf ("%d", section->sh_name);
9419 else
9420 printf ("'%s'", printable_section_name (filedata, section));
9422 uint64_t num_rela = rel_size / section->sh_entsize;
9423 uint64_t rel_offset = section->sh_offset;
9425 if (rel_type == reltype_relr)
9427 /* Just stating the 'number of entries' in a RELR section can be
9428 misleading, since this is not the number of locations relocated, but
9429 the number of words in the compressed RELR format. So also provide
9430 the number of locations affected. */
9432 uint64_t num_reloc = count_relr_relocations (filedata, section);
9434 printf (_(" at offset %#" PRIx64), rel_offset);
9435 printf (ngettext (" contains %" PRIu64 " entry which relocates",
9436 " contains %" PRIu64 " entries which relocate",
9437 num_rela), num_rela);
9438 printf (ngettext (" %" PRIu64 " location:\n",
9439 " %" PRIu64 " locations:\n",
9440 num_reloc), num_reloc);
9442 else
9444 printf (ngettext (" at offset %#" PRIx64
9445 " contains %" PRIu64 " entry:\n",
9446 " at offset %#" PRIx64
9447 " contains %" PRIu64 " entries:\n",
9448 num_rela),
9449 rel_offset, num_rela);
9452 Elf_Internal_Shdr * symsec;
9453 Elf_Internal_Sym * symtab = NULL;
9454 uint64_t nsyms = 0;
9455 uint64_t strtablen = 0;
9456 char * strtab = NULL;
9458 if (section->sh_link == 0
9459 || section->sh_link >= filedata->file_header.e_shnum)
9461 /* Symbol data not available.
9462 This can happen, especially with RELR relocs.
9463 See if there is a .symtab section present.
9464 If so then use it. */
9465 symsec = find_section_by_name (filedata, ".symtab");
9467 else
9469 symsec = filedata->section_headers + section->sh_link;
9471 if (symsec->sh_type != SHT_SYMTAB
9472 && symsec->sh_type != SHT_DYNSYM)
9473 return false;
9476 if (symsec != NULL
9477 && !get_symtab (filedata, symsec, &symtab, &nsyms, &strtab, &strtablen))
9478 return false;
9480 bool res;
9482 if (rel_type == reltype_relr)
9483 res = dump_relr_relocations (filedata, section, symtab, nsyms, strtab, strtablen);
9484 else
9485 res = dump_relocations (filedata, rel_offset, rel_size,
9486 symtab, nsyms, strtab, strtablen,
9487 rel_type,
9488 symsec == NULL ? false : symsec->sh_type == SHT_DYNSYM);
9489 free (strtab);
9490 free (symtab);
9492 return res;
9495 /* Process the reloc section. */
9497 static bool
9498 process_relocs (Filedata * filedata)
9500 uint64_t rel_size;
9501 uint64_t rel_offset;
9503 if (!do_reloc)
9504 return true;
9506 if (do_using_dynamic)
9508 relocation_type rel_type;
9509 const char * name;
9510 bool has_dynamic_reloc;
9511 unsigned int i;
9513 has_dynamic_reloc = false;
9515 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
9517 rel_type = dynamic_relocations [i].rel_type;
9518 name = dynamic_relocations [i].name;
9519 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
9520 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
9522 if (rel_size)
9523 has_dynamic_reloc = true;
9525 if (rel_type == reltype_unknown)
9527 if (dynamic_relocations [i].reloc == DT_JMPREL)
9528 switch (filedata->dynamic_info[DT_PLTREL])
9530 case DT_REL:
9531 rel_type = reltype_rel;
9532 break;
9533 case DT_RELA:
9534 rel_type = reltype_rela;
9535 break;
9539 if (rel_size)
9541 if (filedata->is_separate)
9542 printf
9543 (_("\nIn linked file '%s' section '%s' at offset %#" PRIx64
9544 " contains %" PRId64 " bytes:\n"),
9545 filedata->file_name, name, rel_offset, rel_size);
9546 else
9547 printf
9548 (_("\n'%s' relocation section at offset %#" PRIx64
9549 " contains %" PRId64 " bytes:\n"),
9550 name, rel_offset, rel_size);
9552 dump_relocations (filedata,
9553 offset_from_vma (filedata, rel_offset, rel_size),
9554 rel_size,
9555 filedata->dynamic_symbols,
9556 filedata->num_dynamic_syms,
9557 filedata->dynamic_strings,
9558 filedata->dynamic_strings_length,
9559 rel_type, true /* is_dynamic */);
9563 if (is_ia64_vms (filedata))
9564 if (process_ia64_vms_dynamic_relocs (filedata))
9565 has_dynamic_reloc = true;
9567 if (! has_dynamic_reloc)
9569 if (filedata->is_separate)
9570 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
9571 filedata->file_name);
9572 else
9573 printf (_("\nThere are no dynamic relocations in this file.\n"));
9576 else
9578 Elf_Internal_Shdr * section;
9579 size_t i;
9580 bool found = false;
9582 for (i = 0, section = filedata->section_headers;
9583 i < filedata->file_header.e_shnum;
9584 i++, section++)
9586 if (display_relocations (section, filedata))
9587 found = true;
9590 if (! found)
9592 /* Users sometimes forget the -D option, so try to be helpful. */
9593 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
9595 if (filedata->dynamic_info[dynamic_relocations [i].size])
9597 if (filedata->is_separate)
9598 printf (_("\nThere are no static relocations in linked file '%s'."),
9599 filedata->file_name);
9600 else
9601 printf (_("\nThere are no static relocations in this file."));
9602 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
9604 break;
9607 if (i == ARRAY_SIZE (dynamic_relocations))
9609 if (filedata->is_separate)
9610 printf (_("\nThere are no relocations in linked file '%s'.\n"),
9611 filedata->file_name);
9612 else
9613 printf (_("\nThere are no relocations in this file.\n"));
9618 return true;
9621 /* An absolute address consists of a section and an offset. If the
9622 section is NULL, the offset itself is the address, otherwise, the
9623 address equals to LOAD_ADDRESS(section) + offset. */
9625 struct absaddr
9627 unsigned short section;
9628 uint64_t offset;
9631 /* Find the nearest symbol at or below ADDR. Returns the symbol
9632 name, if found, and the offset from the symbol to ADDR. */
9634 static void
9635 find_symbol_for_address (Filedata *filedata,
9636 Elf_Internal_Sym *symtab,
9637 uint64_t nsyms,
9638 const char *strtab,
9639 uint64_t strtab_size,
9640 struct absaddr addr,
9641 const char **symname,
9642 uint64_t *offset)
9644 uint64_t dist = 0x100000;
9645 Elf_Internal_Sym * sym;
9646 Elf_Internal_Sym * beg;
9647 Elf_Internal_Sym * end;
9648 Elf_Internal_Sym * best = NULL;
9650 REMOVE_ARCH_BITS (addr.offset);
9651 beg = symtab;
9652 end = symtab + nsyms;
9654 while (beg < end)
9656 uint64_t value;
9658 sym = beg + (end - beg) / 2;
9660 value = sym->st_value;
9661 REMOVE_ARCH_BITS (value);
9663 if (sym->st_name != 0
9664 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
9665 && addr.offset >= value
9666 && addr.offset - value < dist)
9668 best = sym;
9669 dist = addr.offset - value;
9670 if (!dist)
9671 break;
9674 if (addr.offset < value)
9675 end = sym;
9676 else
9677 beg = sym + 1;
9680 if (best)
9682 *symname = (best->st_name >= strtab_size
9683 ? _("<corrupt>") : strtab + best->st_name);
9684 *offset = dist;
9685 return;
9688 *symname = NULL;
9689 *offset = addr.offset;
9692 /* Process the unwind section. */
9694 #include "unwind-ia64.h"
9696 struct ia64_unw_table_entry
9698 struct absaddr start;
9699 struct absaddr end;
9700 struct absaddr info;
9703 struct ia64_unw_aux_info
9705 struct ia64_unw_table_entry * table; /* Unwind table. */
9706 uint64_t table_len; /* Length of unwind table. */
9707 unsigned char * info; /* Unwind info. */
9708 uint64_t info_size; /* Size of unwind info. */
9709 uint64_t info_addr; /* Starting address of unwind info. */
9710 uint64_t seg_base; /* Starting address of segment. */
9711 Elf_Internal_Sym * symtab; /* The symbol table. */
9712 uint64_t nsyms; /* Number of symbols. */
9713 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9714 uint64_t nfuns; /* Number of entries in funtab. */
9715 char * strtab; /* The string table. */
9716 uint64_t strtab_size; /* Size of string table. */
9719 static bool
9720 dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
9722 struct ia64_unw_table_entry * tp;
9723 size_t j, nfuns;
9724 int in_body;
9725 bool res = true;
9727 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9728 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9729 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9730 aux->funtab[nfuns++] = aux->symtab[j];
9731 aux->nfuns = nfuns;
9732 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9734 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9736 uint64_t stamp;
9737 uint64_t offset;
9738 const unsigned char * dp;
9739 const unsigned char * head;
9740 const unsigned char * end;
9741 const char * procname;
9743 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
9744 aux->strtab_size, tp->start, &procname, &offset);
9746 fputs ("\n<", stdout);
9748 if (procname)
9750 fputs (procname, stdout);
9752 if (offset)
9753 printf ("+%" PRIx64, offset);
9756 fputs (">: [", stdout);
9757 print_vma (tp->start.offset, PREFIX_HEX);
9758 fputc ('-', stdout);
9759 print_vma (tp->end.offset, PREFIX_HEX);
9760 printf ("], info at +0x%" PRIx64 "\n",
9761 tp->info.offset - aux->seg_base);
9763 /* PR 17531: file: 86232b32. */
9764 if (aux->info == NULL)
9765 continue;
9767 offset = tp->info.offset;
9768 if (tp->info.section)
9770 if (tp->info.section >= filedata->file_header.e_shnum)
9772 warn (_("Invalid section %u in table entry %td\n"),
9773 tp->info.section, tp - aux->table);
9774 res = false;
9775 continue;
9777 offset += filedata->section_headers[tp->info.section].sh_addr;
9779 offset -= aux->info_addr;
9780 /* PR 17531: file: 0997b4d1. */
9781 if (offset >= aux->info_size
9782 || aux->info_size - offset < 8)
9784 warn (_("Invalid offset %" PRIx64 " in table entry %td\n"),
9785 tp->info.offset, tp - aux->table);
9786 res = false;
9787 continue;
9790 head = aux->info + offset;
9791 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
9793 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
9794 (unsigned) UNW_VER (stamp),
9795 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
9796 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
9797 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
9798 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
9800 if (UNW_VER (stamp) != 1)
9802 printf (_("\tUnknown version.\n"));
9803 continue;
9806 in_body = 0;
9807 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
9808 /* PR 17531: file: 16ceda89. */
9809 if (end > aux->info + aux->info_size)
9810 end = aux->info + aux->info_size;
9811 for (dp = head + 8; dp < end;)
9812 dp = unw_decode (dp, in_body, & in_body, end);
9815 free (aux->funtab);
9817 return res;
9820 static bool
9821 slurp_ia64_unwind_table (Filedata * filedata,
9822 struct ia64_unw_aux_info * aux,
9823 Elf_Internal_Shdr * sec)
9825 uint64_t size, nrelas, i;
9826 Elf_Internal_Phdr * seg;
9827 struct ia64_unw_table_entry * tep;
9828 Elf_Internal_Shdr * relsec;
9829 Elf_Internal_Rela * rela;
9830 Elf_Internal_Rela * rp;
9831 unsigned char * table;
9832 unsigned char * tp;
9833 Elf_Internal_Sym * sym;
9834 const char * relname;
9836 aux->table_len = 0;
9838 /* First, find the starting address of the segment that includes
9839 this section: */
9841 if (filedata->file_header.e_phnum)
9843 if (! get_program_headers (filedata))
9844 return false;
9846 for (seg = filedata->program_headers;
9847 seg < filedata->program_headers + filedata->file_header.e_phnum;
9848 ++seg)
9850 if (seg->p_type != PT_LOAD)
9851 continue;
9853 if (sec->sh_addr >= seg->p_vaddr
9854 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9856 aux->seg_base = seg->p_vaddr;
9857 break;
9862 /* Second, build the unwind table from the contents of the unwind section: */
9863 size = sec->sh_size;
9864 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
9865 _("unwind table"));
9866 if (!table)
9867 return false;
9869 aux->table_len = size / (3 * eh_addr_size);
9870 aux->table = (struct ia64_unw_table_entry *)
9871 xcmalloc (aux->table_len, sizeof (aux->table[0]));
9872 tep = aux->table;
9874 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
9876 tep->start.section = SHN_UNDEF;
9877 tep->end.section = SHN_UNDEF;
9878 tep->info.section = SHN_UNDEF;
9879 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9880 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9881 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9882 tep->start.offset += aux->seg_base;
9883 tep->end.offset += aux->seg_base;
9884 tep->info.offset += aux->seg_base;
9886 free (table);
9888 /* Third, apply any relocations to the unwind table: */
9889 for (relsec = filedata->section_headers;
9890 relsec < filedata->section_headers + filedata->file_header.e_shnum;
9891 ++relsec)
9893 if (relsec->sh_type != SHT_RELA
9894 || relsec->sh_info >= filedata->file_header.e_shnum
9895 || filedata->section_headers + relsec->sh_info != sec)
9896 continue;
9898 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
9899 & rela, & nrelas))
9901 free (aux->table);
9902 aux->table = NULL;
9903 aux->table_len = 0;
9904 return false;
9907 for (rp = rela; rp < rela + nrelas; ++rp)
9909 unsigned int sym_ndx;
9910 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9911 relname = elf_ia64_reloc_type (r_type);
9913 /* PR 17531: file: 9fa67536. */
9914 if (relname == NULL)
9916 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9917 continue;
9920 if (! startswith (relname, "R_IA64_SEGREL"))
9922 warn (_("Skipping unexpected relocation type: %s\n"), relname);
9923 continue;
9926 i = rp->r_offset / (3 * eh_addr_size);
9928 /* PR 17531: file: 5bc8d9bf. */
9929 if (i >= aux->table_len)
9931 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9933 continue;
9936 sym_ndx = get_reloc_symindex (rp->r_info);
9937 if (sym_ndx >= aux->nsyms)
9939 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9940 sym_ndx);
9941 continue;
9943 sym = aux->symtab + sym_ndx;
9945 switch (rp->r_offset / eh_addr_size % 3)
9947 case 0:
9948 aux->table[i].start.section = sym->st_shndx;
9949 aux->table[i].start.offset = rp->r_addend + sym->st_value;
9950 break;
9951 case 1:
9952 aux->table[i].end.section = sym->st_shndx;
9953 aux->table[i].end.offset = rp->r_addend + sym->st_value;
9954 break;
9955 case 2:
9956 aux->table[i].info.section = sym->st_shndx;
9957 aux->table[i].info.offset = rp->r_addend + sym->st_value;
9958 break;
9959 default:
9960 break;
9964 free (rela);
9967 return true;
9970 static bool
9971 ia64_process_unwind (Filedata * filedata)
9973 Elf_Internal_Shdr * sec;
9974 Elf_Internal_Shdr * unwsec = NULL;
9975 uint64_t i, unwcount = 0, unwstart = 0;
9976 struct ia64_unw_aux_info aux;
9977 bool res = true;
9979 memset (& aux, 0, sizeof (aux));
9981 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
9983 if (sec->sh_type == SHT_SYMTAB)
9985 if (aux.symtab)
9987 error (_("Multiple symbol tables encountered\n"));
9988 free (aux.symtab);
9989 aux.symtab = NULL;
9990 free (aux.strtab);
9991 aux.strtab = NULL;
9993 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9994 &aux.strtab, &aux.strtab_size))
9995 return false;
9997 else if (sec->sh_type == SHT_IA_64_UNWIND)
9998 unwcount++;
10001 if (!unwcount)
10002 printf (_("\nThere are no unwind sections in this file.\n"));
10004 while (unwcount-- > 0)
10006 const char *suffix;
10007 size_t len, len2;
10009 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
10010 i < filedata->file_header.e_shnum; ++i, ++sec)
10011 if (sec->sh_type == SHT_IA_64_UNWIND)
10013 unwsec = sec;
10014 break;
10016 /* We have already counted the number of SHT_IA64_UNWIND
10017 sections so the loop above should never fail. */
10018 assert (unwsec != NULL);
10020 unwstart = i + 1;
10021 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
10023 if ((unwsec->sh_flags & SHF_GROUP) != 0)
10025 /* We need to find which section group it is in. */
10026 struct group_list * g;
10028 if (filedata->section_headers_groups == NULL
10029 || filedata->section_headers_groups[i] == NULL)
10030 i = filedata->file_header.e_shnum;
10031 else
10033 g = filedata->section_headers_groups[i]->root;
10035 for (; g != NULL; g = g->next)
10037 sec = filedata->section_headers + g->section_index;
10039 if (section_name_valid (filedata, sec)
10040 && streq (section_name (filedata, sec),
10041 ELF_STRING_ia64_unwind_info))
10042 break;
10045 if (g == NULL)
10046 i = filedata->file_header.e_shnum;
10049 else if (section_name_valid (filedata, unwsec)
10050 && startswith (section_name (filedata, unwsec),
10051 ELF_STRING_ia64_unwind_once))
10053 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
10054 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
10055 suffix = section_name (filedata, unwsec) + len;
10056 for (i = 0, sec = filedata->section_headers;
10057 i < filedata->file_header.e_shnum;
10058 ++i, ++sec)
10059 if (section_name_valid (filedata, sec)
10060 && startswith (section_name (filedata, sec),
10061 ELF_STRING_ia64_unwind_info_once)
10062 && streq (section_name (filedata, sec) + len2, suffix))
10063 break;
10065 else
10067 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
10068 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
10069 len = sizeof (ELF_STRING_ia64_unwind) - 1;
10070 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
10071 suffix = "";
10072 if (section_name_valid (filedata, unwsec)
10073 && startswith (section_name (filedata, unwsec),
10074 ELF_STRING_ia64_unwind))
10075 suffix = section_name (filedata, unwsec) + len;
10076 for (i = 0, sec = filedata->section_headers;
10077 i < filedata->file_header.e_shnum;
10078 ++i, ++sec)
10079 if (section_name_valid (filedata, sec)
10080 && startswith (section_name (filedata, sec),
10081 ELF_STRING_ia64_unwind_info)
10082 && streq (section_name (filedata, sec) + len2, suffix))
10083 break;
10086 if (i == filedata->file_header.e_shnum)
10088 printf (_("\nCould not find unwind info section for "));
10090 if (filedata->string_table == NULL)
10091 printf ("%d", unwsec->sh_name);
10092 else
10093 printf ("'%s'", printable_section_name (filedata, unwsec));
10095 else
10097 aux.info_addr = sec->sh_addr;
10098 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
10099 sec->sh_size,
10100 _("unwind info"));
10101 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
10103 printf (_("\nUnwind section "));
10105 if (filedata->string_table == NULL)
10106 printf ("%d", unwsec->sh_name);
10107 else
10108 printf ("'%s'", printable_section_name (filedata, unwsec));
10110 printf (_(" at offset %#" PRIx64 " contains %" PRIu64 " entries:\n"),
10111 unwsec->sh_offset,
10112 unwsec->sh_size / (3 * eh_addr_size));
10114 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
10115 && aux.table_len > 0)
10116 dump_ia64_unwind (filedata, & aux);
10118 free ((char *) aux.table);
10119 free ((char *) aux.info);
10120 aux.table = NULL;
10121 aux.info = NULL;
10125 free (aux.symtab);
10126 free ((char *) aux.strtab);
10128 return res;
10131 struct hppa_unw_table_entry
10133 struct absaddr start;
10134 struct absaddr end;
10135 unsigned int Cannot_unwind:1; /* 0 */
10136 unsigned int Millicode:1; /* 1 */
10137 unsigned int Millicode_save_sr0:1; /* 2 */
10138 unsigned int Region_description:2; /* 3..4 */
10139 unsigned int reserved1:1; /* 5 */
10140 unsigned int Entry_SR:1; /* 6 */
10141 unsigned int Entry_FR:4; /* Number saved 7..10 */
10142 unsigned int Entry_GR:5; /* Number saved 11..15 */
10143 unsigned int Args_stored:1; /* 16 */
10144 unsigned int Variable_Frame:1; /* 17 */
10145 unsigned int Separate_Package_Body:1; /* 18 */
10146 unsigned int Frame_Extension_Millicode:1; /* 19 */
10147 unsigned int Stack_Overflow_Check:1; /* 20 */
10148 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
10149 unsigned int Ada_Region:1; /* 22 */
10150 unsigned int cxx_info:1; /* 23 */
10151 unsigned int cxx_try_catch:1; /* 24 */
10152 unsigned int sched_entry_seq:1; /* 25 */
10153 unsigned int reserved2:1; /* 26 */
10154 unsigned int Save_SP:1; /* 27 */
10155 unsigned int Save_RP:1; /* 28 */
10156 unsigned int Save_MRP_in_frame:1; /* 29 */
10157 unsigned int extn_ptr_defined:1; /* 30 */
10158 unsigned int Cleanup_defined:1; /* 31 */
10160 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
10161 unsigned int HP_UX_interrupt_marker:1; /* 1 */
10162 unsigned int Large_frame:1; /* 2 */
10163 unsigned int Pseudo_SP_Set:1; /* 3 */
10164 unsigned int reserved4:1; /* 4 */
10165 unsigned int Total_frame_size:27; /* 5..31 */
10168 struct hppa_unw_aux_info
10170 struct hppa_unw_table_entry * table; /* Unwind table. */
10171 uint64_t table_len; /* Length of unwind table. */
10172 uint64_t seg_base; /* Starting address of segment. */
10173 Elf_Internal_Sym * symtab; /* The symbol table. */
10174 uint64_t nsyms; /* Number of symbols. */
10175 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
10176 uint64_t nfuns; /* Number of entries in funtab. */
10177 char * strtab; /* The string table. */
10178 uint64_t strtab_size; /* Size of string table. */
10181 static bool
10182 dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
10184 struct hppa_unw_table_entry * tp;
10185 uint64_t j, nfuns;
10186 bool res = true;
10188 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10189 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10190 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10191 aux->funtab[nfuns++] = aux->symtab[j];
10192 aux->nfuns = nfuns;
10193 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10195 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
10197 uint64_t offset;
10198 const char * procname;
10200 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
10201 aux->strtab_size, tp->start, &procname,
10202 &offset);
10204 fputs ("\n<", stdout);
10206 if (procname)
10208 fputs (procname, stdout);
10210 if (offset)
10211 printf ("+%" PRIx64, offset);
10214 fputs (">: [", stdout);
10215 print_vma (tp->start.offset, PREFIX_HEX);
10216 fputc ('-', stdout);
10217 print_vma (tp->end.offset, PREFIX_HEX);
10218 printf ("]\n\t");
10220 #define PF(_m) if (tp->_m) printf (#_m " ");
10221 #define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
10222 PF(Cannot_unwind);
10223 PF(Millicode);
10224 PF(Millicode_save_sr0);
10225 /* PV(Region_description); */
10226 PF(Entry_SR);
10227 PV(Entry_FR);
10228 PV(Entry_GR);
10229 PF(Args_stored);
10230 PF(Variable_Frame);
10231 PF(Separate_Package_Body);
10232 PF(Frame_Extension_Millicode);
10233 PF(Stack_Overflow_Check);
10234 PF(Two_Instruction_SP_Increment);
10235 PF(Ada_Region);
10236 PF(cxx_info);
10237 PF(cxx_try_catch);
10238 PF(sched_entry_seq);
10239 PF(Save_SP);
10240 PF(Save_RP);
10241 PF(Save_MRP_in_frame);
10242 PF(extn_ptr_defined);
10243 PF(Cleanup_defined);
10244 PF(MPE_XL_interrupt_marker);
10245 PF(HP_UX_interrupt_marker);
10246 PF(Large_frame);
10247 PF(Pseudo_SP_Set);
10248 PV(Total_frame_size);
10249 #undef PF
10250 #undef PV
10253 printf ("\n");
10255 free (aux->funtab);
10257 return res;
10260 static bool
10261 slurp_hppa_unwind_table (Filedata * filedata,
10262 struct hppa_unw_aux_info * aux,
10263 Elf_Internal_Shdr * sec)
10265 uint64_t size, unw_ent_size, nentries, nrelas, i;
10266 Elf_Internal_Phdr * seg;
10267 struct hppa_unw_table_entry * tep;
10268 Elf_Internal_Shdr * relsec;
10269 Elf_Internal_Rela * rela;
10270 Elf_Internal_Rela * rp;
10271 unsigned char * table;
10272 unsigned char * tp;
10273 Elf_Internal_Sym * sym;
10274 const char * relname;
10276 /* First, find the starting address of the segment that includes
10277 this section. */
10278 if (filedata->file_header.e_phnum)
10280 if (! get_program_headers (filedata))
10281 return false;
10283 for (seg = filedata->program_headers;
10284 seg < filedata->program_headers + filedata->file_header.e_phnum;
10285 ++seg)
10287 if (seg->p_type != PT_LOAD)
10288 continue;
10290 if (sec->sh_addr >= seg->p_vaddr
10291 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
10293 aux->seg_base = seg->p_vaddr;
10294 break;
10299 /* Second, build the unwind table from the contents of the unwind
10300 section. */
10301 size = sec->sh_size;
10302 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
10303 _("unwind table"));
10304 if (!table)
10305 return false;
10307 unw_ent_size = 16;
10308 nentries = size / unw_ent_size;
10309 size = unw_ent_size * nentries;
10311 aux->table_len = nentries;
10312 tep = aux->table = (struct hppa_unw_table_entry *)
10313 xcmalloc (nentries, sizeof (aux->table[0]));
10315 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
10317 unsigned int tmp1, tmp2;
10319 tep->start.section = SHN_UNDEF;
10320 tep->end.section = SHN_UNDEF;
10322 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
10323 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
10324 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
10325 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
10327 tep->start.offset += aux->seg_base;
10328 tep->end.offset += aux->seg_base;
10330 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
10331 tep->Millicode = (tmp1 >> 30) & 0x1;
10332 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
10333 tep->Region_description = (tmp1 >> 27) & 0x3;
10334 tep->reserved1 = (tmp1 >> 26) & 0x1;
10335 tep->Entry_SR = (tmp1 >> 25) & 0x1;
10336 tep->Entry_FR = (tmp1 >> 21) & 0xf;
10337 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
10338 tep->Args_stored = (tmp1 >> 15) & 0x1;
10339 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
10340 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
10341 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
10342 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
10343 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
10344 tep->Ada_Region = (tmp1 >> 9) & 0x1;
10345 tep->cxx_info = (tmp1 >> 8) & 0x1;
10346 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
10347 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
10348 tep->reserved2 = (tmp1 >> 5) & 0x1;
10349 tep->Save_SP = (tmp1 >> 4) & 0x1;
10350 tep->Save_RP = (tmp1 >> 3) & 0x1;
10351 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
10352 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
10353 tep->Cleanup_defined = tmp1 & 0x1;
10355 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
10356 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
10357 tep->Large_frame = (tmp2 >> 29) & 0x1;
10358 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
10359 tep->reserved4 = (tmp2 >> 27) & 0x1;
10360 tep->Total_frame_size = tmp2 & 0x7ffffff;
10362 free (table);
10364 /* Third, apply any relocations to the unwind table. */
10365 for (relsec = filedata->section_headers;
10366 relsec < filedata->section_headers + filedata->file_header.e_shnum;
10367 ++relsec)
10369 if (relsec->sh_type != SHT_RELA
10370 || relsec->sh_info >= filedata->file_header.e_shnum
10371 || filedata->section_headers + relsec->sh_info != sec)
10372 continue;
10374 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
10375 & rela, & nrelas))
10376 return false;
10378 for (rp = rela; rp < rela + nrelas; ++rp)
10380 unsigned int sym_ndx;
10381 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
10382 relname = elf_hppa_reloc_type (r_type);
10384 if (relname == NULL)
10386 warn (_("Skipping unknown relocation type: %u\n"), r_type);
10387 continue;
10390 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
10391 if (! startswith (relname, "R_PARISC_SEGREL"))
10393 warn (_("Skipping unexpected relocation type: %s\n"), relname);
10394 continue;
10397 i = rp->r_offset / unw_ent_size;
10398 if (i >= aux->table_len)
10400 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
10402 continue;
10405 sym_ndx = get_reloc_symindex (rp->r_info);
10406 if (sym_ndx >= aux->nsyms)
10408 warn (_("Skipping reloc with invalid symbol index: %u\n"),
10409 sym_ndx);
10410 continue;
10412 sym = aux->symtab + sym_ndx;
10414 switch ((rp->r_offset % unw_ent_size) / 4)
10416 case 0:
10417 aux->table[i].start.section = sym->st_shndx;
10418 aux->table[i].start.offset = sym->st_value + rp->r_addend;
10419 break;
10420 case 1:
10421 aux->table[i].end.section = sym->st_shndx;
10422 aux->table[i].end.offset = sym->st_value + rp->r_addend;
10423 break;
10424 default:
10425 break;
10429 free (rela);
10432 return true;
10435 static bool
10436 hppa_process_unwind (Filedata * filedata)
10438 struct hppa_unw_aux_info aux;
10439 Elf_Internal_Shdr * unwsec = NULL;
10440 Elf_Internal_Shdr * sec;
10441 size_t i;
10442 bool res = true;
10444 if (filedata->string_table == NULL)
10445 return false;
10447 memset (& aux, 0, sizeof (aux));
10449 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
10451 if (sec->sh_type == SHT_SYMTAB)
10453 if (aux.symtab)
10455 error (_("Multiple symbol tables encountered\n"));
10456 free (aux.symtab);
10457 aux.symtab = NULL;
10458 free (aux.strtab);
10459 aux.strtab = NULL;
10461 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10462 &aux.strtab, &aux.strtab_size))
10463 return false;
10465 else if (section_name_valid (filedata, sec)
10466 && streq (section_name (filedata, sec), ".PARISC.unwind"))
10467 unwsec = sec;
10470 if (!unwsec)
10471 printf (_("\nThere are no unwind sections in this file.\n"));
10473 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
10475 if (section_name_valid (filedata, sec)
10476 && streq (section_name (filedata, sec), ".PARISC.unwind"))
10478 uint64_t num_unwind = sec->sh_size / 16;
10480 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
10481 "contains %" PRIu64 " entry:\n",
10482 "\nUnwind section '%s' at offset %#" PRIx64 " "
10483 "contains %" PRIu64 " entries:\n",
10484 num_unwind),
10485 printable_section_name (filedata, sec),
10486 sec->sh_offset,
10487 num_unwind);
10489 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
10490 res = false;
10492 if (res && aux.table_len > 0)
10494 if (! dump_hppa_unwind (filedata, &aux))
10495 res = false;
10498 free ((char *) aux.table);
10499 aux.table = NULL;
10503 free (aux.symtab);
10504 free ((char *) aux.strtab);
10506 return res;
10509 struct arm_section
10511 unsigned char * data; /* The unwind data. */
10512 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
10513 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
10514 uint64_t nrelas; /* The number of relocations. */
10515 unsigned int rel_type; /* REL or RELA ? */
10516 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
10519 struct arm_unw_aux_info
10521 Filedata * filedata; /* The file containing the unwind sections. */
10522 Elf_Internal_Sym * symtab; /* The file's symbol table. */
10523 uint64_t nsyms; /* Number of symbols. */
10524 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
10525 uint64_t nfuns; /* Number of these symbols. */
10526 char * strtab; /* The file's string table. */
10527 uint64_t strtab_size; /* Size of string table. */
10530 static const char *
10531 arm_print_vma_and_name (Filedata * filedata,
10532 struct arm_unw_aux_info * aux,
10533 uint64_t fn,
10534 struct absaddr addr)
10536 const char *procname;
10537 uint64_t sym_offset;
10539 if (addr.section == SHN_UNDEF)
10540 addr.offset = fn;
10542 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
10543 aux->strtab_size, addr, &procname,
10544 &sym_offset);
10546 print_vma (fn, PREFIX_HEX);
10548 if (procname)
10550 fputs (" <", stdout);
10551 fputs (procname, stdout);
10553 if (sym_offset)
10554 printf ("+0x%" PRIx64, sym_offset);
10555 fputc ('>', stdout);
10558 return procname;
10561 static void
10562 arm_free_section (struct arm_section *arm_sec)
10564 free (arm_sec->data);
10565 free (arm_sec->rela);
10568 /* 1) If SEC does not match the one cached in ARM_SEC, then free the current
10569 cached section and install SEC instead.
10570 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
10571 and return its valued in * WORDP, relocating if necessary.
10572 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
10573 relocation's offset in ADDR.
10574 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
10575 into the string table of the symbol associated with the reloc. If no
10576 reloc was applied store -1 there.
10577 5) Return TRUE upon success, FALSE otherwise. */
10579 static bool
10580 get_unwind_section_word (Filedata * filedata,
10581 struct arm_unw_aux_info * aux,
10582 struct arm_section * arm_sec,
10583 Elf_Internal_Shdr * sec,
10584 uint64_t word_offset,
10585 unsigned int * wordp,
10586 struct absaddr * addr,
10587 uint64_t * sym_name)
10589 Elf_Internal_Rela *rp;
10590 Elf_Internal_Sym *sym;
10591 const char * relname;
10592 unsigned int word;
10593 bool wrapped;
10595 if (sec == NULL || arm_sec == NULL)
10596 return false;
10598 addr->section = SHN_UNDEF;
10599 addr->offset = 0;
10601 if (sym_name != NULL)
10602 *sym_name = (uint64_t) -1;
10604 /* If necessary, update the section cache. */
10605 if (sec != arm_sec->sec)
10607 Elf_Internal_Shdr *relsec;
10609 arm_free_section (arm_sec);
10611 arm_sec->sec = sec;
10612 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
10613 sec->sh_size, _("unwind data"));
10614 arm_sec->rela = NULL;
10615 arm_sec->nrelas = 0;
10617 for (relsec = filedata->section_headers;
10618 relsec < filedata->section_headers + filedata->file_header.e_shnum;
10619 ++relsec)
10621 if (relsec->sh_info >= filedata->file_header.e_shnum
10622 || filedata->section_headers + relsec->sh_info != sec
10623 /* PR 15745: Check the section type as well. */
10624 || (relsec->sh_type != SHT_REL
10625 && relsec->sh_type != SHT_RELA))
10626 continue;
10628 arm_sec->rel_type = relsec->sh_type;
10629 if (relsec->sh_type == SHT_REL)
10631 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
10632 relsec->sh_size,
10633 & arm_sec->rela, & arm_sec->nrelas))
10634 return false;
10636 else /* relsec->sh_type == SHT_RELA */
10638 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
10639 relsec->sh_size,
10640 & arm_sec->rela, & arm_sec->nrelas))
10641 return false;
10643 break;
10646 arm_sec->next_rela = arm_sec->rela;
10649 /* If there is no unwind data we can do nothing. */
10650 if (arm_sec->data == NULL)
10651 return false;
10653 /* If the offset is invalid then fail. */
10654 if (/* PR 21343 *//* PR 18879 */
10655 sec->sh_size < 4
10656 || word_offset > sec->sh_size - 4)
10657 return false;
10659 /* Get the word at the required offset. */
10660 word = byte_get (arm_sec->data + word_offset, 4);
10662 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
10663 if (arm_sec->rela == NULL)
10665 * wordp = word;
10666 return true;
10669 /* Look through the relocs to find the one that applies to the provided offset. */
10670 wrapped = false;
10671 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
10673 uint64_t prelval, offset;
10675 if (rp->r_offset > word_offset && !wrapped)
10677 rp = arm_sec->rela;
10678 wrapped = true;
10680 if (rp->r_offset > word_offset)
10681 break;
10683 if (rp->r_offset & 3)
10685 warn (_("Skipping unexpected relocation at offset %#" PRIx64 "\n"),
10686 rp->r_offset);
10687 continue;
10690 if (rp->r_offset < word_offset)
10691 continue;
10693 /* PR 17531: file: 027-161405-0.004 */
10694 if (aux->symtab == NULL)
10695 continue;
10697 if (arm_sec->rel_type == SHT_REL)
10699 offset = word & 0x7fffffff;
10700 if (offset & 0x40000000)
10701 offset |= ~ (uint64_t) 0x7fffffff;
10703 else if (arm_sec->rel_type == SHT_RELA)
10704 offset = rp->r_addend;
10705 else
10707 error (_("Unknown section relocation type %d encountered\n"),
10708 arm_sec->rel_type);
10709 break;
10712 /* PR 17531 file: 027-1241568-0.004. */
10713 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
10715 error (_("Bad symbol index in unwind relocation "
10716 "(%" PRIu64 " > %" PRIu64 ")\n"),
10717 ELF32_R_SYM (rp->r_info), aux->nsyms);
10718 break;
10721 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
10722 offset += sym->st_value;
10723 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
10725 /* Check that we are processing the expected reloc type. */
10726 if (filedata->file_header.e_machine == EM_ARM)
10728 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
10729 if (relname == NULL)
10731 warn (_("Skipping unknown ARM relocation type: %d\n"),
10732 (int) ELF32_R_TYPE (rp->r_info));
10733 continue;
10736 if (streq (relname, "R_ARM_NONE"))
10737 continue;
10739 if (! streq (relname, "R_ARM_PREL31"))
10741 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
10742 continue;
10745 else if (filedata->file_header.e_machine == EM_TI_C6000)
10747 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
10748 if (relname == NULL)
10750 warn (_("Skipping unknown C6000 relocation type: %d\n"),
10751 (int) ELF32_R_TYPE (rp->r_info));
10752 continue;
10755 if (streq (relname, "R_C6000_NONE"))
10756 continue;
10758 if (! streq (relname, "R_C6000_PREL31"))
10760 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
10761 continue;
10764 prelval >>= 1;
10766 else
10768 /* This function currently only supports ARM and TI unwinders. */
10769 warn (_("Only TI and ARM unwinders are currently supported\n"));
10770 break;
10773 word = (word & ~ (uint64_t) 0x7fffffff) | (prelval & 0x7fffffff);
10774 addr->section = sym->st_shndx;
10775 addr->offset = offset;
10777 if (sym_name)
10778 * sym_name = sym->st_name;
10779 break;
10782 *wordp = word;
10783 arm_sec->next_rela = rp;
10785 return true;
10788 static const char *tic6x_unwind_regnames[16] =
10790 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
10791 "A14", "A13", "A12", "A11", "A10",
10792 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
10795 static void
10796 decode_tic6x_unwind_regmask (unsigned int mask)
10798 int i;
10800 for (i = 12; mask; mask >>= 1, i--)
10802 if (mask & 1)
10804 fputs (tic6x_unwind_regnames[i], stdout);
10805 if (mask > 1)
10806 fputs (", ", stdout);
10811 #define ADVANCE \
10812 if (remaining == 0 && more_words) \
10814 data_offset += 4; \
10815 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
10816 data_offset, & word, & addr, NULL)) \
10817 return false; \
10818 remaining = 4; \
10819 more_words--; \
10822 #define GET_OP(OP) \
10823 ADVANCE; \
10824 if (remaining) \
10826 remaining--; \
10827 (OP) = word >> 24; \
10828 word <<= 8; \
10830 else \
10832 printf (_("[Truncated opcode]\n")); \
10833 return false; \
10835 printf ("0x%02x ", OP)
10837 static bool
10838 decode_arm_unwind_bytecode (Filedata * filedata,
10839 struct arm_unw_aux_info * aux,
10840 unsigned int word,
10841 unsigned int remaining,
10842 unsigned int more_words,
10843 uint64_t data_offset,
10844 Elf_Internal_Shdr * data_sec,
10845 struct arm_section * data_arm_sec)
10847 struct absaddr addr;
10848 bool res = true;
10850 /* Decode the unwinding instructions. */
10851 while (1)
10853 unsigned int op, op2;
10855 ADVANCE;
10856 if (remaining == 0)
10857 break;
10858 remaining--;
10859 op = word >> 24;
10860 word <<= 8;
10862 printf (" 0x%02x ", op);
10864 if ((op & 0xc0) == 0x00)
10866 int offset = ((op & 0x3f) << 2) + 4;
10868 printf (" vsp = vsp + %d", offset);
10870 else if ((op & 0xc0) == 0x40)
10872 int offset = ((op & 0x3f) << 2) + 4;
10874 printf (" vsp = vsp - %d", offset);
10876 else if ((op & 0xf0) == 0x80)
10878 GET_OP (op2);
10879 if (op == 0x80 && op2 == 0)
10880 printf (_("Refuse to unwind"));
10881 else
10883 unsigned int mask = ((op & 0x0f) << 8) | op2;
10884 bool first = true;
10885 int i;
10887 printf ("pop {");
10888 for (i = 0; i < 12; i++)
10889 if (mask & (1 << i))
10891 if (first)
10892 first = false;
10893 else
10894 printf (", ");
10895 printf ("r%d", 4 + i);
10897 printf ("}");
10900 else if ((op & 0xf0) == 0x90)
10902 if (op == 0x9d || op == 0x9f)
10903 printf (_(" [Reserved]"));
10904 else
10905 printf (" vsp = r%d", op & 0x0f);
10907 else if ((op & 0xf0) == 0xa0)
10909 int end = 4 + (op & 0x07);
10910 bool first = true;
10911 int i;
10913 printf (" pop {");
10914 for (i = 4; i <= end; i++)
10916 if (first)
10917 first = false;
10918 else
10919 printf (", ");
10920 printf ("r%d", i);
10922 if (op & 0x08)
10924 if (!first)
10925 printf (", ");
10926 printf ("r14");
10928 printf ("}");
10930 else if (op == 0xb0)
10931 printf (_(" finish"));
10932 else if (op == 0xb1)
10934 GET_OP (op2);
10935 if (op2 == 0 || (op2 & 0xf0) != 0)
10936 printf (_("[Spare]"));
10937 else
10939 unsigned int mask = op2 & 0x0f;
10940 bool first = true;
10941 int i;
10943 printf ("pop {");
10944 for (i = 0; i < 12; i++)
10945 if (mask & (1 << i))
10947 if (first)
10948 first = false;
10949 else
10950 printf (", ");
10951 printf ("r%d", i);
10953 printf ("}");
10956 else if (op == 0xb2)
10958 unsigned char buf[9];
10959 unsigned int i, len;
10960 uint64_t offset;
10962 for (i = 0; i < sizeof (buf); i++)
10964 GET_OP (buf[i]);
10965 if ((buf[i] & 0x80) == 0)
10966 break;
10968 if (i == sizeof (buf))
10970 error (_("corrupt change to vsp\n"));
10971 res = false;
10973 else
10975 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
10976 assert (len == i + 1);
10977 offset = offset * 4 + 0x204;
10978 printf ("vsp = vsp + %" PRId64, offset);
10981 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
10983 unsigned int first, last;
10985 GET_OP (op2);
10986 first = op2 >> 4;
10987 last = op2 & 0x0f;
10988 if (op == 0xc8)
10989 first = first + 16;
10990 printf ("pop {D%d", first);
10991 if (last)
10992 printf ("-D%d", first + last);
10993 printf ("}");
10995 else if (op == 0xb4)
10996 printf (_(" pop {ra_auth_code}"));
10997 else if (op == 0xb5)
10998 printf (_(" vsp as modifier for PAC validation"));
10999 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
11001 unsigned int count = op & 0x07;
11003 printf ("pop {D8");
11004 if (count)
11005 printf ("-D%d", 8 + count);
11006 printf ("}");
11008 else if (op >= 0xc0 && op <= 0xc5)
11010 unsigned int count = op & 0x07;
11012 printf (" pop {wR10");
11013 if (count)
11014 printf ("-wR%d", 10 + count);
11015 printf ("}");
11017 else if (op == 0xc6)
11019 unsigned int first, last;
11021 GET_OP (op2);
11022 first = op2 >> 4;
11023 last = op2 & 0x0f;
11024 printf ("pop {wR%d", first);
11025 if (last)
11026 printf ("-wR%d", first + last);
11027 printf ("}");
11029 else if (op == 0xc7)
11031 GET_OP (op2);
11032 if (op2 == 0 || (op2 & 0xf0) != 0)
11033 printf (_("[Spare]"));
11034 else
11036 unsigned int mask = op2 & 0x0f;
11037 bool first = true;
11038 int i;
11040 printf ("pop {");
11041 for (i = 0; i < 4; i++)
11042 if (mask & (1 << i))
11044 if (first)
11045 first = false;
11046 else
11047 printf (", ");
11048 printf ("wCGR%d", i);
11050 printf ("}");
11053 else
11055 printf (_(" [unsupported opcode]"));
11056 res = false;
11059 printf ("\n");
11062 return res;
11065 static bool
11066 decode_tic6x_unwind_bytecode (Filedata * filedata,
11067 struct arm_unw_aux_info * aux,
11068 unsigned int word,
11069 unsigned int remaining,
11070 unsigned int more_words,
11071 uint64_t data_offset,
11072 Elf_Internal_Shdr * data_sec,
11073 struct arm_section * data_arm_sec)
11075 struct absaddr addr;
11077 /* Decode the unwinding instructions. */
11078 while (1)
11080 unsigned int op, op2;
11082 ADVANCE;
11083 if (remaining == 0)
11084 break;
11085 remaining--;
11086 op = word >> 24;
11087 word <<= 8;
11089 printf (" 0x%02x ", op);
11091 if ((op & 0xc0) == 0x00)
11093 int offset = ((op & 0x3f) << 3) + 8;
11094 printf (" sp = sp + %d", offset);
11096 else if ((op & 0xc0) == 0x80)
11098 GET_OP (op2);
11099 if (op == 0x80 && op2 == 0)
11100 printf (_("Refuse to unwind"));
11101 else
11103 unsigned int mask = ((op & 0x1f) << 8) | op2;
11104 if (op & 0x20)
11105 printf ("pop compact {");
11106 else
11107 printf ("pop {");
11109 decode_tic6x_unwind_regmask (mask);
11110 printf("}");
11113 else if ((op & 0xf0) == 0xc0)
11115 unsigned int reg;
11116 unsigned int nregs;
11117 unsigned int i;
11118 const char *name;
11119 struct
11121 unsigned int offset;
11122 unsigned int reg;
11123 } regpos[16];
11125 /* Scan entire instruction first so that GET_OP output is not
11126 interleaved with disassembly. */
11127 nregs = 0;
11128 for (i = 0; nregs < (op & 0xf); i++)
11130 GET_OP (op2);
11131 reg = op2 >> 4;
11132 if (reg != 0xf)
11134 regpos[nregs].offset = i * 2;
11135 regpos[nregs].reg = reg;
11136 nregs++;
11139 reg = op2 & 0xf;
11140 if (reg != 0xf)
11142 regpos[nregs].offset = i * 2 + 1;
11143 regpos[nregs].reg = reg;
11144 nregs++;
11148 printf (_("pop frame {"));
11149 if (nregs == 0)
11151 printf (_("*corrupt* - no registers specified"));
11153 else
11155 reg = nregs - 1;
11156 for (i = i * 2; i > 0; i--)
11158 if (regpos[reg].offset == i - 1)
11160 name = tic6x_unwind_regnames[regpos[reg].reg];
11161 if (reg > 0)
11162 reg--;
11164 else
11165 name = _("[pad]");
11167 fputs (name, stdout);
11168 if (i > 1)
11169 printf (", ");
11173 printf ("}");
11175 else if (op == 0xd0)
11176 printf (" MOV FP, SP");
11177 else if (op == 0xd1)
11178 printf (" __c6xabi_pop_rts");
11179 else if (op == 0xd2)
11181 unsigned char buf[9];
11182 unsigned int i, len;
11183 uint64_t offset;
11185 for (i = 0; i < sizeof (buf); i++)
11187 GET_OP (buf[i]);
11188 if ((buf[i] & 0x80) == 0)
11189 break;
11191 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
11192 if (i == sizeof (buf))
11194 warn (_("Corrupt stack pointer adjustment detected\n"));
11195 return false;
11198 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
11199 assert (len == i + 1);
11200 offset = offset * 8 + 0x408;
11201 printf (_("sp = sp + %" PRId64), offset);
11203 else if ((op & 0xf0) == 0xe0)
11205 if ((op & 0x0f) == 7)
11206 printf (" RETURN");
11207 else
11208 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
11210 else
11212 printf (_(" [unsupported opcode]"));
11214 putchar ('\n');
11217 return true;
11220 static uint64_t
11221 arm_expand_prel31 (Filedata * filedata, uint64_t word, uint64_t where)
11223 uint64_t offset;
11225 offset = word & 0x7fffffff;
11226 if (offset & 0x40000000)
11227 offset |= ~ (uint64_t) 0x7fffffff;
11229 if (filedata->file_header.e_machine == EM_TI_C6000)
11230 offset <<= 1;
11232 return offset + where;
11235 static bool
11236 decode_arm_unwind (Filedata * filedata,
11237 struct arm_unw_aux_info * aux,
11238 unsigned int word,
11239 unsigned int remaining,
11240 uint64_t data_offset,
11241 Elf_Internal_Shdr * data_sec,
11242 struct arm_section * data_arm_sec)
11244 int per_index;
11245 unsigned int more_words = 0;
11246 struct absaddr addr;
11247 uint64_t sym_name = (uint64_t) -1;
11248 bool res = true;
11250 if (remaining == 0)
11252 /* Fetch the first word.
11253 Note - when decoding an object file the address extracted
11254 here will always be 0. So we also pass in the sym_name
11255 parameter so that we can find the symbol associated with
11256 the personality routine. */
11257 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
11258 & word, & addr, & sym_name))
11259 return false;
11261 remaining = 4;
11263 else
11265 addr.section = SHN_UNDEF;
11266 addr.offset = 0;
11269 if ((word & 0x80000000) == 0)
11271 /* Expand prel31 for personality routine. */
11272 uint64_t fn;
11273 const char *procname;
11275 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
11276 printf (_(" Personality routine: "));
11277 if (fn == 0
11278 && addr.section == SHN_UNDEF && addr.offset == 0
11279 && sym_name != (uint64_t) -1 && sym_name < aux->strtab_size)
11281 procname = aux->strtab + sym_name;
11282 print_vma (fn, PREFIX_HEX);
11283 if (procname)
11285 fputs (" <", stdout);
11286 fputs (procname, stdout);
11287 fputc ('>', stdout);
11290 else
11291 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
11292 fputc ('\n', stdout);
11294 /* The GCC personality routines use the standard compact
11295 encoding, starting with one byte giving the number of
11296 words. */
11297 if (procname != NULL
11298 && (startswith (procname, "__gcc_personality_v0")
11299 || startswith (procname, "__gxx_personality_v0")
11300 || startswith (procname, "__gcj_personality_v0")
11301 || startswith (procname, "__gnu_objc_personality_v0")))
11303 remaining = 0;
11304 more_words = 1;
11305 ADVANCE;
11306 if (!remaining)
11308 printf (_(" [Truncated data]\n"));
11309 return false;
11311 more_words = word >> 24;
11312 word <<= 8;
11313 remaining--;
11314 per_index = -1;
11316 else
11317 return true;
11319 else
11321 /* ARM EHABI Section 6.3:
11323 An exception-handling table entry for the compact model looks like:
11325 31 30-28 27-24 23-0
11326 -- ----- ----- ----
11327 1 0 index Data for personalityRoutine[index] */
11329 if (filedata->file_header.e_machine == EM_ARM
11330 && (word & 0x70000000))
11332 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
11333 res = false;
11336 per_index = (word >> 24) & 0x7f;
11337 printf (_(" Compact model index: %d\n"), per_index);
11338 if (per_index == 0)
11340 more_words = 0;
11341 word <<= 8;
11342 remaining--;
11344 else if (per_index < 3)
11346 more_words = (word >> 16) & 0xff;
11347 word <<= 16;
11348 remaining -= 2;
11352 switch (filedata->file_header.e_machine)
11354 case EM_ARM:
11355 if (per_index < 3)
11357 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
11358 data_offset, data_sec, data_arm_sec))
11359 res = false;
11361 else
11363 warn (_("Unknown ARM compact model index encountered\n"));
11364 printf (_(" [reserved]\n"));
11365 res = false;
11367 break;
11369 case EM_TI_C6000:
11370 if (per_index < 3)
11372 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
11373 data_offset, data_sec, data_arm_sec))
11374 res = false;
11376 else if (per_index < 5)
11378 if (((word >> 17) & 0x7f) == 0x7f)
11379 printf (_(" Restore stack from frame pointer\n"));
11380 else
11381 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
11382 printf (_(" Registers restored: "));
11383 if (per_index == 4)
11384 printf (" (compact) ");
11385 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
11386 putchar ('\n');
11387 printf (_(" Return register: %s\n"),
11388 tic6x_unwind_regnames[word & 0xf]);
11390 else
11391 printf (_(" [reserved (%d)]\n"), per_index);
11392 break;
11394 default:
11395 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
11396 filedata->file_header.e_machine);
11397 res = false;
11400 /* Decode the descriptors. Not implemented. */
11402 return res;
11405 static bool
11406 dump_arm_unwind (Filedata * filedata,
11407 struct arm_unw_aux_info * aux,
11408 Elf_Internal_Shdr * exidx_sec)
11410 struct arm_section exidx_arm_sec, extab_arm_sec;
11411 unsigned int i, exidx_len;
11412 uint64_t j, nfuns;
11413 bool res = true;
11415 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
11416 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
11417 exidx_len = exidx_sec->sh_size / 8;
11419 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
11420 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
11421 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
11422 aux->funtab[nfuns++] = aux->symtab[j];
11423 aux->nfuns = nfuns;
11424 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
11426 for (i = 0; i < exidx_len; i++)
11428 unsigned int exidx_fn, exidx_entry;
11429 struct absaddr fn_addr, entry_addr;
11430 uint64_t fn;
11432 fputc ('\n', stdout);
11434 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
11435 8 * i, & exidx_fn, & fn_addr, NULL)
11436 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
11437 8 * i + 4, & exidx_entry, & entry_addr, NULL))
11439 free (aux->funtab);
11440 arm_free_section (& exidx_arm_sec);
11441 arm_free_section (& extab_arm_sec);
11442 return false;
11445 /* ARM EHABI, Section 5:
11446 An index table entry consists of 2 words.
11447 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
11448 if (exidx_fn & 0x80000000)
11450 warn (_("corrupt index table entry: %x\n"), exidx_fn);
11451 res = false;
11454 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
11456 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
11457 fputs (": ", stdout);
11459 if (exidx_entry == 1)
11461 print_vma (exidx_entry, PREFIX_HEX);
11462 fputs (" [cantunwind]\n", stdout);
11464 else if (exidx_entry & 0x80000000)
11466 print_vma (exidx_entry, PREFIX_HEX);
11467 fputc ('\n', stdout);
11468 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
11470 else
11472 uint64_t table, table_offset = 0;
11473 Elf_Internal_Shdr *table_sec;
11475 fputs ("@", stdout);
11476 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
11477 print_vma (table, PREFIX_HEX);
11478 printf ("\n");
11480 /* Locate the matching .ARM.extab. */
11481 if (entry_addr.section != SHN_UNDEF
11482 && entry_addr.section < filedata->file_header.e_shnum)
11484 table_sec = filedata->section_headers + entry_addr.section;
11485 table_offset = entry_addr.offset;
11486 /* PR 18879 */
11487 if (table_offset > table_sec->sh_size)
11489 warn (_("Unwind entry contains corrupt offset (%#" PRIx64 ") into section %s\n"),
11490 table_offset,
11491 printable_section_name (filedata, table_sec));
11492 res = false;
11493 continue;
11496 else
11498 table_sec = find_section_by_address (filedata, table);
11499 if (table_sec != NULL)
11500 table_offset = table - table_sec->sh_addr;
11503 if (table_sec == NULL)
11505 warn (_("Could not locate .ARM.extab section containing %#" PRIx64 ".\n"),
11506 table);
11507 res = false;
11508 continue;
11511 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
11512 &extab_arm_sec))
11513 res = false;
11517 printf ("\n");
11519 free (aux->funtab);
11520 arm_free_section (&exidx_arm_sec);
11521 arm_free_section (&extab_arm_sec);
11523 return res;
11526 /* Used for both ARM and C6X unwinding tables. */
11528 static bool
11529 arm_process_unwind (Filedata * filedata)
11531 struct arm_unw_aux_info aux;
11532 Elf_Internal_Shdr *unwsec = NULL;
11533 Elf_Internal_Shdr *sec;
11534 size_t i;
11535 unsigned int sec_type;
11536 bool res = true;
11538 switch (filedata->file_header.e_machine)
11540 case EM_ARM:
11541 sec_type = SHT_ARM_EXIDX;
11542 break;
11544 case EM_TI_C6000:
11545 sec_type = SHT_C6000_UNWIND;
11546 break;
11548 default:
11549 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
11550 filedata->file_header.e_machine);
11551 return false;
11554 if (filedata->string_table == NULL)
11555 return false;
11557 memset (& aux, 0, sizeof (aux));
11558 aux.filedata = filedata;
11560 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
11562 if (sec->sh_type == SHT_SYMTAB)
11564 if (aux.symtab)
11566 error (_("Multiple symbol tables encountered\n"));
11567 free (aux.symtab);
11568 aux.symtab = NULL;
11569 free (aux.strtab);
11570 aux.strtab = NULL;
11572 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
11573 &aux.strtab, &aux.strtab_size))
11574 return false;
11576 else if (sec->sh_type == sec_type)
11577 unwsec = sec;
11580 if (unwsec == NULL)
11581 printf (_("\nThere are no unwind sections in this file.\n"));
11582 else
11583 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
11585 if (sec->sh_type == sec_type)
11587 uint64_t num_unwind = sec->sh_size / (2 * eh_addr_size);
11588 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
11589 "contains %" PRIu64 " entry:\n",
11590 "\nUnwind section '%s' at offset %#" PRIx64 " "
11591 "contains %" PRIu64 " entries:\n",
11592 num_unwind),
11593 printable_section_name (filedata, sec),
11594 sec->sh_offset,
11595 num_unwind);
11597 if (! dump_arm_unwind (filedata, &aux, sec))
11598 res = false;
11602 free (aux.symtab);
11603 free ((char *) aux.strtab);
11605 return res;
11608 static bool
11609 no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
11611 printf (_("No processor specific unwind information to decode\n"));
11612 return true;
11615 static bool
11616 process_unwind (Filedata * filedata)
11618 struct unwind_handler
11620 unsigned int machtype;
11621 bool (* handler)(Filedata *);
11622 } handlers[] =
11624 { EM_ARM, arm_process_unwind },
11625 { EM_IA_64, ia64_process_unwind },
11626 { EM_PARISC, hppa_process_unwind },
11627 { EM_TI_C6000, arm_process_unwind },
11628 { EM_386, no_processor_specific_unwind },
11629 { EM_X86_64, no_processor_specific_unwind },
11630 { 0, NULL }
11632 int i;
11634 if (!do_unwind)
11635 return true;
11637 for (i = 0; handlers[i].handler != NULL; i++)
11638 if (filedata->file_header.e_machine == handlers[i].machtype)
11639 return handlers[i].handler (filedata);
11641 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
11642 get_machine_name (filedata->file_header.e_machine));
11643 return true;
11646 static void
11647 dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
11649 switch (entry->d_tag)
11651 case DT_AARCH64_BTI_PLT:
11652 case DT_AARCH64_PAC_PLT:
11653 break;
11654 default:
11655 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11656 break;
11658 putchar ('\n');
11661 static void
11662 dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
11664 switch (entry->d_tag)
11666 case DT_MIPS_FLAGS:
11667 if (entry->d_un.d_val == 0)
11668 printf (_("NONE"));
11669 else
11671 static const char * opts[] =
11673 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
11674 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
11675 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
11676 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
11677 "RLD_ORDER_SAFE"
11679 unsigned int cnt;
11680 bool first = true;
11682 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
11683 if (entry->d_un.d_val & (1 << cnt))
11685 printf ("%s%s", first ? "" : " ", opts[cnt]);
11686 first = false;
11689 break;
11691 case DT_MIPS_IVERSION:
11692 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11693 printf (_("Interface Version: %s"),
11694 get_dynamic_name (filedata, entry->d_un.d_val));
11695 else
11696 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
11697 entry->d_un.d_ptr);
11698 break;
11700 case DT_MIPS_TIME_STAMP:
11702 char timebuf[128];
11703 struct tm * tmp;
11704 time_t atime = entry->d_un.d_val;
11706 tmp = gmtime (&atime);
11707 /* PR 17531: file: 6accc532. */
11708 if (tmp == NULL)
11709 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
11710 else
11711 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
11712 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11713 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
11714 printf (_("Time Stamp: %s"), timebuf);
11716 break;
11718 case DT_MIPS_RLD_VERSION:
11719 case DT_MIPS_LOCAL_GOTNO:
11720 case DT_MIPS_CONFLICTNO:
11721 case DT_MIPS_LIBLISTNO:
11722 case DT_MIPS_SYMTABNO:
11723 case DT_MIPS_UNREFEXTNO:
11724 case DT_MIPS_HIPAGENO:
11725 case DT_MIPS_DELTA_CLASS_NO:
11726 case DT_MIPS_DELTA_INSTANCE_NO:
11727 case DT_MIPS_DELTA_RELOC_NO:
11728 case DT_MIPS_DELTA_SYM_NO:
11729 case DT_MIPS_DELTA_CLASSSYM_NO:
11730 case DT_MIPS_COMPACT_SIZE:
11731 print_vma (entry->d_un.d_val, DEC);
11732 break;
11734 case DT_MIPS_XHASH:
11735 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11736 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
11737 /* Falls through. */
11739 default:
11740 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11742 putchar ('\n');
11745 static void
11746 dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
11748 switch (entry->d_tag)
11750 case DT_HP_DLD_FLAGS:
11752 static struct
11754 unsigned int bit;
11755 const char * str;
11757 flags[] =
11759 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
11760 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
11761 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
11762 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
11763 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
11764 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
11765 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
11766 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
11767 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
11768 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
11769 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
11770 { DT_HP_GST, "HP_GST" },
11771 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
11772 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
11773 { DT_HP_NODELETE, "HP_NODELETE" },
11774 { DT_HP_GROUP, "HP_GROUP" },
11775 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
11777 bool first = true;
11778 size_t cnt;
11779 uint64_t val = entry->d_un.d_val;
11781 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
11782 if (val & flags[cnt].bit)
11784 if (! first)
11785 putchar (' ');
11786 fputs (flags[cnt].str, stdout);
11787 first = false;
11788 val ^= flags[cnt].bit;
11791 if (val != 0 || first)
11793 if (! first)
11794 putchar (' ');
11795 print_vma (val, HEX);
11798 break;
11800 default:
11801 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11802 break;
11804 putchar ('\n');
11807 /* VMS vs Unix time offset and factor. */
11809 #define VMS_EPOCH_OFFSET 35067168000000000LL
11810 #define VMS_GRANULARITY_FACTOR 10000000
11811 #ifndef INT64_MIN
11812 #define INT64_MIN (-9223372036854775807LL - 1)
11813 #endif
11815 /* Display a VMS time in a human readable format. */
11817 static void
11818 print_vms_time (int64_t vmstime)
11820 struct tm *tm = NULL;
11821 time_t unxtime;
11823 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
11825 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
11826 unxtime = vmstime;
11827 if (unxtime == vmstime)
11828 tm = gmtime (&unxtime);
11830 if (tm != NULL)
11831 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
11832 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
11833 tm->tm_hour, tm->tm_min, tm->tm_sec);
11836 static void
11837 dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
11839 switch (entry->d_tag)
11841 case DT_IA_64_PLT_RESERVE:
11842 /* First 3 slots reserved. */
11843 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11844 printf (" -- ");
11845 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
11846 break;
11848 case DT_IA_64_VMS_LINKTIME:
11849 print_vms_time (entry->d_un.d_val);
11850 break;
11852 case DT_IA_64_VMS_LNKFLAGS:
11853 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11854 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
11855 printf (" CALL_DEBUG");
11856 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
11857 printf (" NOP0BUFS");
11858 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
11859 printf (" P0IMAGE");
11860 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
11861 printf (" MKTHREADS");
11862 if (entry->d_un.d_val & VMS_LF_UPCALLS)
11863 printf (" UPCALLS");
11864 if (entry->d_un.d_val & VMS_LF_IMGSTA)
11865 printf (" IMGSTA");
11866 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
11867 printf (" INITIALIZE");
11868 if (entry->d_un.d_val & VMS_LF_MAIN)
11869 printf (" MAIN");
11870 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
11871 printf (" EXE_INIT");
11872 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
11873 printf (" TBK_IN_IMG");
11874 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
11875 printf (" DBG_IN_IMG");
11876 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
11877 printf (" TBK_IN_DSF");
11878 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
11879 printf (" DBG_IN_DSF");
11880 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
11881 printf (" SIGNATURES");
11882 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
11883 printf (" REL_SEG_OFF");
11884 break;
11886 default:
11887 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11888 break;
11890 putchar ('\n');
11893 static bool
11894 get_32bit_dynamic_section (Filedata * filedata)
11896 Elf32_External_Dyn * edyn;
11897 Elf32_External_Dyn * ext;
11898 Elf_Internal_Dyn * entry;
11900 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
11901 filedata->dynamic_addr, 1,
11902 filedata->dynamic_size,
11903 _("dynamic section"));
11904 if (!edyn)
11905 return false;
11907 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11908 might not have the luxury of section headers. Look for the DT_NULL
11909 terminator to determine the number of entries. */
11910 for (ext = edyn, filedata->dynamic_nent = 0;
11911 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
11912 ext++)
11914 filedata->dynamic_nent++;
11915 if (BYTE_GET (ext->d_tag) == DT_NULL)
11916 break;
11919 filedata->dynamic_section
11920 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11921 if (filedata->dynamic_section == NULL)
11923 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11924 filedata->dynamic_nent);
11925 free (edyn);
11926 return false;
11929 for (ext = edyn, entry = filedata->dynamic_section;
11930 entry < filedata->dynamic_section + filedata->dynamic_nent;
11931 ext++, entry++)
11933 entry->d_tag = BYTE_GET (ext->d_tag);
11934 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
11937 free (edyn);
11939 return true;
11942 static bool
11943 get_64bit_dynamic_section (Filedata * filedata)
11945 Elf64_External_Dyn * edyn;
11946 Elf64_External_Dyn * ext;
11947 Elf_Internal_Dyn * entry;
11949 /* Read in the data. */
11950 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
11951 filedata->dynamic_addr, 1,
11952 filedata->dynamic_size,
11953 _("dynamic section"));
11954 if (!edyn)
11955 return false;
11957 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11958 might not have the luxury of section headers. Look for the DT_NULL
11959 terminator to determine the number of entries. */
11960 for (ext = edyn, filedata->dynamic_nent = 0;
11961 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
11962 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
11963 ext++)
11965 filedata->dynamic_nent++;
11966 if (BYTE_GET (ext->d_tag) == DT_NULL)
11967 break;
11970 filedata->dynamic_section
11971 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11972 if (filedata->dynamic_section == NULL)
11974 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11975 filedata->dynamic_nent);
11976 free (edyn);
11977 return false;
11980 /* Convert from external to internal formats. */
11981 for (ext = edyn, entry = filedata->dynamic_section;
11982 entry < filedata->dynamic_section + filedata->dynamic_nent;
11983 ext++, entry++)
11985 entry->d_tag = BYTE_GET (ext->d_tag);
11986 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
11989 free (edyn);
11991 return true;
11994 static bool
11995 get_dynamic_section (Filedata *filedata)
11997 if (filedata->dynamic_section)
11998 return true;
12000 if (is_32bit_elf)
12001 return get_32bit_dynamic_section (filedata);
12002 else
12003 return get_64bit_dynamic_section (filedata);
12006 static void
12007 print_dynamic_flags (uint64_t flags)
12009 bool first = true;
12011 while (flags)
12013 uint64_t flag;
12015 flag = flags & - flags;
12016 flags &= ~ flag;
12018 if (first)
12019 first = false;
12020 else
12021 putc (' ', stdout);
12023 switch (flag)
12025 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
12026 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
12027 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
12028 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
12029 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
12030 default: fputs (_("unknown"), stdout); break;
12033 puts ("");
12036 static uint64_t *
12037 get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
12039 unsigned char * e_data;
12040 uint64_t * i_data;
12042 /* If size_t is smaller than uint64_t, eg because you are building
12043 on a 32-bit host, then make sure that when number is cast to
12044 size_t no information is lost. */
12045 if ((size_t) number != number
12046 || ent_size * number / ent_size != number)
12048 error (_("Size overflow prevents reading %" PRIu64
12049 " elements of size %u\n"),
12050 number, ent_size);
12051 return NULL;
12054 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
12055 attempting to allocate memory when the read is bound to fail. */
12056 if (ent_size * number > filedata->file_size)
12058 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
12059 number);
12060 return NULL;
12063 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
12064 if (e_data == NULL)
12066 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
12067 number);
12068 return NULL;
12071 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
12073 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
12074 number * ent_size);
12075 free (e_data);
12076 return NULL;
12079 i_data = (uint64_t *) cmalloc ((size_t) number, sizeof (*i_data));
12080 if (i_data == NULL)
12082 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
12083 number);
12084 free (e_data);
12085 return NULL;
12088 while (number--)
12089 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
12091 free (e_data);
12093 return i_data;
12096 static uint64_t
12097 get_num_dynamic_syms (Filedata * filedata)
12099 uint64_t num_of_syms = 0;
12101 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
12102 return num_of_syms;
12104 if (filedata->dynamic_info[DT_HASH])
12106 unsigned char nb[8];
12107 unsigned char nc[8];
12108 unsigned int hash_ent_size = 4;
12110 if ((filedata->file_header.e_machine == EM_ALPHA
12111 || filedata->file_header.e_machine == EM_S390
12112 || filedata->file_header.e_machine == EM_S390_OLD)
12113 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
12114 hash_ent_size = 8;
12116 if (fseek64 (filedata->handle,
12117 (filedata->archive_file_offset
12118 + offset_from_vma (filedata,
12119 filedata->dynamic_info[DT_HASH],
12120 sizeof nb + sizeof nc)),
12121 SEEK_SET))
12123 error (_("Unable to seek to start of dynamic information\n"));
12124 goto no_hash;
12127 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
12129 error (_("Failed to read in number of buckets\n"));
12130 goto no_hash;
12133 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
12135 error (_("Failed to read in number of chains\n"));
12136 goto no_hash;
12139 filedata->nbuckets = byte_get (nb, hash_ent_size);
12140 filedata->nchains = byte_get (nc, hash_ent_size);
12142 if (filedata->nbuckets != 0 && filedata->nchains != 0)
12144 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
12145 hash_ent_size);
12146 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
12147 hash_ent_size);
12149 if (filedata->buckets != NULL && filedata->chains != NULL)
12150 num_of_syms = filedata->nchains;
12152 no_hash:
12153 if (num_of_syms == 0)
12155 free (filedata->buckets);
12156 filedata->buckets = NULL;
12157 free (filedata->chains);
12158 filedata->chains = NULL;
12159 filedata->nbuckets = 0;
12163 if (filedata->dynamic_info_DT_GNU_HASH)
12165 unsigned char nb[16];
12166 uint64_t i, maxchain = 0xffffffff, bitmaskwords;
12167 uint64_t buckets_vma;
12168 uint64_t hn;
12170 if (fseek64 (filedata->handle,
12171 (filedata->archive_file_offset
12172 + offset_from_vma (filedata,
12173 filedata->dynamic_info_DT_GNU_HASH,
12174 sizeof nb)),
12175 SEEK_SET))
12177 error (_("Unable to seek to start of dynamic information\n"));
12178 goto no_gnu_hash;
12181 if (fread (nb, 16, 1, filedata->handle) != 1)
12183 error (_("Failed to read in number of buckets\n"));
12184 goto no_gnu_hash;
12187 filedata->ngnubuckets = byte_get (nb, 4);
12188 filedata->gnusymidx = byte_get (nb + 4, 4);
12189 bitmaskwords = byte_get (nb + 8, 4);
12190 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
12191 if (is_32bit_elf)
12192 buckets_vma += bitmaskwords * 4;
12193 else
12194 buckets_vma += bitmaskwords * 8;
12196 if (fseek64 (filedata->handle,
12197 (filedata->archive_file_offset
12198 + offset_from_vma (filedata, buckets_vma, 4)),
12199 SEEK_SET))
12201 error (_("Unable to seek to start of dynamic information\n"));
12202 goto no_gnu_hash;
12205 filedata->gnubuckets
12206 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
12208 if (filedata->gnubuckets == NULL)
12209 goto no_gnu_hash;
12211 for (i = 0; i < filedata->ngnubuckets; i++)
12212 if (filedata->gnubuckets[i] != 0)
12214 if (filedata->gnubuckets[i] < filedata->gnusymidx)
12215 goto no_gnu_hash;
12217 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
12218 maxchain = filedata->gnubuckets[i];
12221 if (maxchain == 0xffffffff)
12222 goto no_gnu_hash;
12224 maxchain -= filedata->gnusymidx;
12226 if (fseek64 (filedata->handle,
12227 (filedata->archive_file_offset
12228 + offset_from_vma (filedata,
12229 buckets_vma + 4 * (filedata->ngnubuckets
12230 + maxchain),
12231 4)),
12232 SEEK_SET))
12234 error (_("Unable to seek to start of dynamic information\n"));
12235 goto no_gnu_hash;
12240 if (fread (nb, 4, 1, filedata->handle) != 1)
12242 error (_("Failed to determine last chain length\n"));
12243 goto no_gnu_hash;
12246 if (maxchain + 1 == 0)
12247 goto no_gnu_hash;
12249 ++maxchain;
12251 while ((byte_get (nb, 4) & 1) == 0);
12253 if (fseek64 (filedata->handle,
12254 (filedata->archive_file_offset
12255 + offset_from_vma (filedata, (buckets_vma
12256 + 4 * filedata->ngnubuckets),
12257 4)),
12258 SEEK_SET))
12260 error (_("Unable to seek to start of dynamic information\n"));
12261 goto no_gnu_hash;
12264 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
12265 filedata->ngnuchains = maxchain;
12267 if (filedata->gnuchains == NULL)
12268 goto no_gnu_hash;
12270 if (filedata->dynamic_info_DT_MIPS_XHASH)
12272 if (fseek64 (filedata->handle,
12273 (filedata->archive_file_offset
12274 + offset_from_vma (filedata, (buckets_vma
12275 + 4 * (filedata->ngnubuckets
12276 + maxchain)), 4)),
12277 SEEK_SET))
12279 error (_("Unable to seek to start of dynamic information\n"));
12280 goto no_gnu_hash;
12283 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
12284 if (filedata->mipsxlat == NULL)
12285 goto no_gnu_hash;
12288 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
12289 if (filedata->gnubuckets[hn] != 0)
12291 uint64_t si = filedata->gnubuckets[hn];
12292 uint64_t off = si - filedata->gnusymidx;
12296 if (filedata->dynamic_info_DT_MIPS_XHASH)
12298 if (off < filedata->ngnuchains
12299 && filedata->mipsxlat[off] >= num_of_syms)
12300 num_of_syms = filedata->mipsxlat[off] + 1;
12302 else
12304 if (si >= num_of_syms)
12305 num_of_syms = si + 1;
12307 si++;
12309 while (off < filedata->ngnuchains
12310 && (filedata->gnuchains[off++] & 1) == 0);
12313 if (num_of_syms == 0)
12315 no_gnu_hash:
12316 free (filedata->mipsxlat);
12317 filedata->mipsxlat = NULL;
12318 free (filedata->gnuchains);
12319 filedata->gnuchains = NULL;
12320 free (filedata->gnubuckets);
12321 filedata->gnubuckets = NULL;
12322 filedata->ngnubuckets = 0;
12323 filedata->ngnuchains = 0;
12327 return num_of_syms;
12330 /* Parse and display the contents of the dynamic section. */
12332 static bool
12333 process_dynamic_section (Filedata * filedata)
12335 Elf_Internal_Dyn * entry;
12337 if (filedata->dynamic_size <= 1)
12339 if (do_dynamic)
12341 if (filedata->is_separate)
12342 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
12343 filedata->file_name);
12344 else
12345 printf (_("\nThere is no dynamic section in this file.\n"));
12348 return true;
12351 if (!get_dynamic_section (filedata))
12352 return false;
12354 /* Find the appropriate symbol table. */
12355 if (filedata->dynamic_symbols == NULL || do_histogram)
12357 uint64_t num_of_syms;
12359 for (entry = filedata->dynamic_section;
12360 entry < filedata->dynamic_section + filedata->dynamic_nent;
12361 ++entry)
12362 if (entry->d_tag == DT_SYMTAB)
12363 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
12364 else if (entry->d_tag == DT_SYMENT)
12365 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
12366 else if (entry->d_tag == DT_HASH)
12367 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
12368 else if (entry->d_tag == DT_GNU_HASH)
12369 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
12370 else if ((filedata->file_header.e_machine == EM_MIPS
12371 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
12372 && entry->d_tag == DT_MIPS_XHASH)
12374 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
12375 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
12378 num_of_syms = get_num_dynamic_syms (filedata);
12380 if (num_of_syms != 0
12381 && filedata->dynamic_symbols == NULL
12382 && filedata->dynamic_info[DT_SYMTAB]
12383 && filedata->dynamic_info[DT_SYMENT])
12385 Elf_Internal_Phdr *seg;
12386 uint64_t vma = filedata->dynamic_info[DT_SYMTAB];
12388 if (! get_program_headers (filedata))
12390 error (_("Cannot interpret virtual addresses "
12391 "without program headers.\n"));
12392 return false;
12395 for (seg = filedata->program_headers;
12396 seg < filedata->program_headers + filedata->file_header.e_phnum;
12397 ++seg)
12399 if (seg->p_type != PT_LOAD)
12400 continue;
12402 if (seg->p_offset + seg->p_filesz > filedata->file_size)
12404 /* See PR 21379 for a reproducer. */
12405 error (_("Invalid PT_LOAD entry\n"));
12406 return false;
12409 if (vma >= (seg->p_vaddr & -seg->p_align)
12410 && vma < seg->p_vaddr + seg->p_filesz)
12412 /* Since we do not know how big the symbol table is,
12413 we default to reading in up to the end of PT_LOAD
12414 segment and processing that. This is overkill, I
12415 know, but it should work. */
12416 Elf_Internal_Shdr section;
12417 section.sh_offset = (vma - seg->p_vaddr
12418 + seg->p_offset);
12419 section.sh_size = (num_of_syms
12420 * filedata->dynamic_info[DT_SYMENT]);
12421 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
12423 if (do_checks
12424 && filedata->dynamic_symtab_section != NULL
12425 && ((filedata->dynamic_symtab_section->sh_offset
12426 != section.sh_offset)
12427 || (filedata->dynamic_symtab_section->sh_size
12428 != section.sh_size)
12429 || (filedata->dynamic_symtab_section->sh_entsize
12430 != section.sh_entsize)))
12431 warn (_("\
12432 the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
12434 section.sh_name = filedata->string_table_length;
12435 filedata->dynamic_symbols
12436 = get_elf_symbols (filedata, &section,
12437 &filedata->num_dynamic_syms);
12438 if (filedata->dynamic_symbols == NULL
12439 || filedata->num_dynamic_syms != num_of_syms)
12441 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
12442 return false;
12444 break;
12450 /* Similarly find a string table. */
12451 if (filedata->dynamic_strings == NULL)
12452 for (entry = filedata->dynamic_section;
12453 entry < filedata->dynamic_section + filedata->dynamic_nent;
12454 ++entry)
12456 if (entry->d_tag == DT_STRTAB)
12457 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
12459 if (entry->d_tag == DT_STRSZ)
12460 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
12462 if (filedata->dynamic_info[DT_STRTAB]
12463 && filedata->dynamic_info[DT_STRSZ])
12465 uint64_t offset;
12466 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
12468 offset = offset_from_vma (filedata,
12469 filedata->dynamic_info[DT_STRTAB],
12470 str_tab_len);
12471 if (do_checks
12472 && filedata->dynamic_strtab_section
12473 && ((filedata->dynamic_strtab_section->sh_offset
12474 != (file_ptr) offset)
12475 || (filedata->dynamic_strtab_section->sh_size
12476 != str_tab_len)))
12477 warn (_("\
12478 the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
12480 filedata->dynamic_strings
12481 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
12482 _("dynamic string table"));
12483 if (filedata->dynamic_strings == NULL)
12485 error (_("Corrupt DT_STRTAB dynamic entry\n"));
12486 break;
12489 filedata->dynamic_strings_length = str_tab_len;
12490 break;
12494 /* And find the syminfo section if available. */
12495 if (filedata->dynamic_syminfo == NULL)
12497 uint64_t syminsz = 0;
12499 for (entry = filedata->dynamic_section;
12500 entry < filedata->dynamic_section + filedata->dynamic_nent;
12501 ++entry)
12503 if (entry->d_tag == DT_SYMINENT)
12505 /* Note: these braces are necessary to avoid a syntax
12506 error from the SunOS4 C compiler. */
12507 /* PR binutils/17531: A corrupt file can trigger this test.
12508 So do not use an assert, instead generate an error message. */
12509 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
12510 error (_("Bad value (%d) for SYMINENT entry\n"),
12511 (int) entry->d_un.d_val);
12513 else if (entry->d_tag == DT_SYMINSZ)
12514 syminsz = entry->d_un.d_val;
12515 else if (entry->d_tag == DT_SYMINFO)
12516 filedata->dynamic_syminfo_offset
12517 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
12520 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
12522 Elf_External_Syminfo * extsyminfo;
12523 Elf_External_Syminfo * extsym;
12524 Elf_Internal_Syminfo * syminfo;
12526 /* There is a syminfo section. Read the data. */
12527 extsyminfo = (Elf_External_Syminfo *)
12528 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
12529 1, syminsz, _("symbol information"));
12530 if (!extsyminfo)
12531 return false;
12533 if (filedata->dynamic_syminfo != NULL)
12535 error (_("Multiple dynamic symbol information sections found\n"));
12536 free (filedata->dynamic_syminfo);
12538 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
12539 if (filedata->dynamic_syminfo == NULL)
12541 error (_("Out of memory allocating %" PRIu64
12542 " bytes for dynamic symbol info\n"),
12543 syminsz);
12544 return false;
12547 filedata->dynamic_syminfo_nent
12548 = syminsz / sizeof (Elf_External_Syminfo);
12549 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
12550 syminfo < (filedata->dynamic_syminfo
12551 + filedata->dynamic_syminfo_nent);
12552 ++syminfo, ++extsym)
12554 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
12555 syminfo->si_flags = BYTE_GET (extsym->si_flags);
12558 free (extsyminfo);
12562 if (do_dynamic && filedata->dynamic_addr)
12564 if (filedata->is_separate)
12565 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
12566 "\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
12567 filedata->dynamic_nent),
12568 filedata->file_name,
12569 filedata->dynamic_addr,
12570 filedata->dynamic_nent);
12571 else
12572 printf (ngettext ("\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
12573 "\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
12574 filedata->dynamic_nent),
12575 filedata->dynamic_addr,
12576 filedata->dynamic_nent);
12578 if (do_dynamic)
12579 printf (_(" Tag Type Name/Value\n"));
12581 for (entry = filedata->dynamic_section;
12582 entry < filedata->dynamic_section + filedata->dynamic_nent;
12583 entry++)
12585 if (do_dynamic)
12587 const char * dtype;
12589 putchar (' ');
12590 print_vma (entry->d_tag, FULL_HEX);
12591 dtype = get_dynamic_type (filedata, entry->d_tag);
12592 printf (" (%s)%*s", dtype,
12593 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
12596 switch (entry->d_tag)
12598 case DT_FLAGS:
12599 if (do_dynamic)
12600 print_dynamic_flags (entry->d_un.d_val);
12601 break;
12603 case DT_AUXILIARY:
12604 case DT_FILTER:
12605 case DT_CONFIG:
12606 case DT_DEPAUDIT:
12607 case DT_AUDIT:
12608 if (do_dynamic)
12610 switch (entry->d_tag)
12612 case DT_AUXILIARY:
12613 printf (_("Auxiliary library"));
12614 break;
12616 case DT_FILTER:
12617 printf (_("Filter library"));
12618 break;
12620 case DT_CONFIG:
12621 printf (_("Configuration file"));
12622 break;
12624 case DT_DEPAUDIT:
12625 printf (_("Dependency audit library"));
12626 break;
12628 case DT_AUDIT:
12629 printf (_("Audit library"));
12630 break;
12633 if (valid_dynamic_name (filedata, entry->d_un.d_val))
12634 printf (": [%s]\n",
12635 get_dynamic_name (filedata, entry->d_un.d_val));
12636 else
12638 printf (": ");
12639 print_vma (entry->d_un.d_val, PREFIX_HEX);
12640 putchar ('\n');
12643 break;
12645 case DT_FEATURE:
12646 if (do_dynamic)
12648 printf (_("Flags:"));
12650 if (entry->d_un.d_val == 0)
12651 printf (_(" None\n"));
12652 else
12654 uint64_t val = entry->d_un.d_val;
12656 if (val & DTF_1_PARINIT)
12658 printf (" PARINIT");
12659 val ^= DTF_1_PARINIT;
12661 if (val & DTF_1_CONFEXP)
12663 printf (" CONFEXP");
12664 val ^= DTF_1_CONFEXP;
12666 if (val != 0)
12667 printf (" %" PRIx64, val);
12668 puts ("");
12671 break;
12673 case DT_POSFLAG_1:
12674 if (do_dynamic)
12676 printf (_("Flags:"));
12678 if (entry->d_un.d_val == 0)
12679 printf (_(" None\n"));
12680 else
12682 uint64_t val = entry->d_un.d_val;
12684 if (val & DF_P1_LAZYLOAD)
12686 printf (" LAZYLOAD");
12687 val ^= DF_P1_LAZYLOAD;
12689 if (val & DF_P1_GROUPPERM)
12691 printf (" GROUPPERM");
12692 val ^= DF_P1_GROUPPERM;
12694 if (val != 0)
12695 printf (" %" PRIx64, val);
12696 puts ("");
12699 break;
12701 case DT_FLAGS_1:
12702 if (do_dynamic)
12704 printf (_("Flags:"));
12705 if (entry->d_un.d_val == 0)
12706 printf (_(" None\n"));
12707 else
12709 uint64_t val = entry->d_un.d_val;
12711 if (val & DF_1_NOW)
12713 printf (" NOW");
12714 val ^= DF_1_NOW;
12716 if (val & DF_1_GLOBAL)
12718 printf (" GLOBAL");
12719 val ^= DF_1_GLOBAL;
12721 if (val & DF_1_GROUP)
12723 printf (" GROUP");
12724 val ^= DF_1_GROUP;
12726 if (val & DF_1_NODELETE)
12728 printf (" NODELETE");
12729 val ^= DF_1_NODELETE;
12731 if (val & DF_1_LOADFLTR)
12733 printf (" LOADFLTR");
12734 val ^= DF_1_LOADFLTR;
12736 if (val & DF_1_INITFIRST)
12738 printf (" INITFIRST");
12739 val ^= DF_1_INITFIRST;
12741 if (val & DF_1_NOOPEN)
12743 printf (" NOOPEN");
12744 val ^= DF_1_NOOPEN;
12746 if (val & DF_1_ORIGIN)
12748 printf (" ORIGIN");
12749 val ^= DF_1_ORIGIN;
12751 if (val & DF_1_DIRECT)
12753 printf (" DIRECT");
12754 val ^= DF_1_DIRECT;
12756 if (val & DF_1_TRANS)
12758 printf (" TRANS");
12759 val ^= DF_1_TRANS;
12761 if (val & DF_1_INTERPOSE)
12763 printf (" INTERPOSE");
12764 val ^= DF_1_INTERPOSE;
12766 if (val & DF_1_NODEFLIB)
12768 printf (" NODEFLIB");
12769 val ^= DF_1_NODEFLIB;
12771 if (val & DF_1_NODUMP)
12773 printf (" NODUMP");
12774 val ^= DF_1_NODUMP;
12776 if (val & DF_1_CONFALT)
12778 printf (" CONFALT");
12779 val ^= DF_1_CONFALT;
12781 if (val & DF_1_ENDFILTEE)
12783 printf (" ENDFILTEE");
12784 val ^= DF_1_ENDFILTEE;
12786 if (val & DF_1_DISPRELDNE)
12788 printf (" DISPRELDNE");
12789 val ^= DF_1_DISPRELDNE;
12791 if (val & DF_1_DISPRELPND)
12793 printf (" DISPRELPND");
12794 val ^= DF_1_DISPRELPND;
12796 if (val & DF_1_NODIRECT)
12798 printf (" NODIRECT");
12799 val ^= DF_1_NODIRECT;
12801 if (val & DF_1_IGNMULDEF)
12803 printf (" IGNMULDEF");
12804 val ^= DF_1_IGNMULDEF;
12806 if (val & DF_1_NOKSYMS)
12808 printf (" NOKSYMS");
12809 val ^= DF_1_NOKSYMS;
12811 if (val & DF_1_NOHDR)
12813 printf (" NOHDR");
12814 val ^= DF_1_NOHDR;
12816 if (val & DF_1_EDITED)
12818 printf (" EDITED");
12819 val ^= DF_1_EDITED;
12821 if (val & DF_1_NORELOC)
12823 printf (" NORELOC");
12824 val ^= DF_1_NORELOC;
12826 if (val & DF_1_SYMINTPOSE)
12828 printf (" SYMINTPOSE");
12829 val ^= DF_1_SYMINTPOSE;
12831 if (val & DF_1_GLOBAUDIT)
12833 printf (" GLOBAUDIT");
12834 val ^= DF_1_GLOBAUDIT;
12836 if (val & DF_1_SINGLETON)
12838 printf (" SINGLETON");
12839 val ^= DF_1_SINGLETON;
12841 if (val & DF_1_STUB)
12843 printf (" STUB");
12844 val ^= DF_1_STUB;
12846 if (val & DF_1_PIE)
12848 printf (" PIE");
12849 val ^= DF_1_PIE;
12851 if (val & DF_1_KMOD)
12853 printf (" KMOD");
12854 val ^= DF_1_KMOD;
12856 if (val & DF_1_WEAKFILTER)
12858 printf (" WEAKFILTER");
12859 val ^= DF_1_WEAKFILTER;
12861 if (val & DF_1_NOCOMMON)
12863 printf (" NOCOMMON");
12864 val ^= DF_1_NOCOMMON;
12866 if (val != 0)
12867 printf (" %" PRIx64, val);
12868 puts ("");
12871 break;
12873 case DT_PLTREL:
12874 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
12875 if (do_dynamic)
12876 puts (get_dynamic_type (filedata, entry->d_un.d_val));
12877 break;
12879 case DT_NULL :
12880 case DT_NEEDED :
12881 case DT_PLTGOT :
12882 case DT_HASH :
12883 case DT_STRTAB :
12884 case DT_SYMTAB :
12885 case DT_RELA :
12886 case DT_INIT :
12887 case DT_FINI :
12888 case DT_SONAME :
12889 case DT_RPATH :
12890 case DT_SYMBOLIC:
12891 case DT_REL :
12892 case DT_RELR :
12893 case DT_DEBUG :
12894 case DT_TEXTREL :
12895 case DT_JMPREL :
12896 case DT_RUNPATH :
12897 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
12899 if (do_dynamic)
12901 const char *name;
12903 if (valid_dynamic_name (filedata, entry->d_un.d_val))
12904 name = get_dynamic_name (filedata, entry->d_un.d_val);
12905 else
12906 name = NULL;
12908 if (name)
12910 switch (entry->d_tag)
12912 case DT_NEEDED:
12913 printf (_("Shared library: [%s]"), name);
12915 if (filedata->program_interpreter
12916 && streq (name, filedata->program_interpreter))
12917 printf (_(" program interpreter"));
12918 break;
12920 case DT_SONAME:
12921 printf (_("Library soname: [%s]"), name);
12922 break;
12924 case DT_RPATH:
12925 printf (_("Library rpath: [%s]"), name);
12926 break;
12928 case DT_RUNPATH:
12929 printf (_("Library runpath: [%s]"), name);
12930 break;
12932 default:
12933 print_vma (entry->d_un.d_val, PREFIX_HEX);
12934 break;
12937 else
12938 print_vma (entry->d_un.d_val, PREFIX_HEX);
12940 putchar ('\n');
12942 break;
12944 case DT_PLTRELSZ:
12945 case DT_RELASZ :
12946 case DT_STRSZ :
12947 case DT_RELSZ :
12948 case DT_RELAENT :
12949 case DT_RELRENT :
12950 case DT_RELRSZ :
12951 case DT_SYMENT :
12952 case DT_RELENT :
12953 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
12954 /* Fall through. */
12955 case DT_PLTPADSZ:
12956 case DT_MOVEENT :
12957 case DT_MOVESZ :
12958 case DT_PREINIT_ARRAYSZ:
12959 case DT_INIT_ARRAYSZ:
12960 case DT_FINI_ARRAYSZ:
12961 case DT_GNU_CONFLICTSZ:
12962 case DT_GNU_LIBLISTSZ:
12963 if (do_dynamic)
12965 print_vma (entry->d_un.d_val, UNSIGNED);
12966 printf (_(" (bytes)\n"));
12968 break;
12970 case DT_VERDEFNUM:
12971 case DT_VERNEEDNUM:
12972 case DT_RELACOUNT:
12973 case DT_RELCOUNT:
12974 if (do_dynamic)
12976 print_vma (entry->d_un.d_val, UNSIGNED);
12977 putchar ('\n');
12979 break;
12981 case DT_SYMINSZ:
12982 case DT_SYMINENT:
12983 case DT_SYMINFO:
12984 case DT_USED:
12985 case DT_INIT_ARRAY:
12986 case DT_FINI_ARRAY:
12987 if (do_dynamic)
12989 if (entry->d_tag == DT_USED
12990 && valid_dynamic_name (filedata, entry->d_un.d_val))
12992 const char *name
12993 = get_dynamic_name (filedata, entry->d_un.d_val);
12995 if (*name)
12997 printf (_("Not needed object: [%s]\n"), name);
12998 break;
13002 print_vma (entry->d_un.d_val, PREFIX_HEX);
13003 putchar ('\n');
13005 break;
13007 case DT_BIND_NOW:
13008 /* The value of this entry is ignored. */
13009 if (do_dynamic)
13010 putchar ('\n');
13011 break;
13013 case DT_GNU_PRELINKED:
13014 if (do_dynamic)
13016 struct tm * tmp;
13017 time_t atime = entry->d_un.d_val;
13019 tmp = gmtime (&atime);
13020 /* PR 17533 file: 041-1244816-0.004. */
13021 if (tmp == NULL)
13022 printf (_("<corrupt time val: %" PRIx64),
13023 (uint64_t) atime);
13024 else
13025 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
13026 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
13027 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
13030 break;
13032 case DT_GNU_HASH:
13033 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
13034 if (do_dynamic)
13036 print_vma (entry->d_un.d_val, PREFIX_HEX);
13037 putchar ('\n');
13039 break;
13041 case DT_GNU_FLAGS_1:
13042 if (do_dynamic)
13044 printf (_("Flags:"));
13045 if (entry->d_un.d_val == 0)
13046 printf (_(" None\n"));
13047 else
13049 uint64_t val = entry->d_un.d_val;
13051 if (val & DF_GNU_1_UNIQUE)
13053 printf (" UNIQUE");
13054 val ^= DF_GNU_1_UNIQUE;
13056 if (val != 0)
13057 printf (" %" PRIx64, val);
13058 puts ("");
13061 break;
13063 default:
13064 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
13065 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
13066 = entry->d_un.d_val;
13068 if (do_dynamic)
13070 switch (filedata->file_header.e_machine)
13072 case EM_AARCH64:
13073 dynamic_section_aarch64_val (entry);
13074 break;
13075 case EM_MIPS:
13076 case EM_MIPS_RS3_LE:
13077 dynamic_section_mips_val (filedata, entry);
13078 break;
13079 case EM_PARISC:
13080 dynamic_section_parisc_val (entry);
13081 break;
13082 case EM_IA_64:
13083 dynamic_section_ia64_val (entry);
13084 break;
13085 default:
13086 print_vma (entry->d_un.d_val, PREFIX_HEX);
13087 putchar ('\n');
13090 break;
13094 return true;
13097 static char *
13098 get_ver_flags (unsigned int flags)
13100 static char buff[128];
13102 buff[0] = 0;
13104 if (flags == 0)
13105 return _("none");
13107 if (flags & VER_FLG_BASE)
13108 strcat (buff, "BASE");
13110 if (flags & VER_FLG_WEAK)
13112 if (flags & VER_FLG_BASE)
13113 strcat (buff, " | ");
13115 strcat (buff, "WEAK");
13118 if (flags & VER_FLG_INFO)
13120 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
13121 strcat (buff, " | ");
13123 strcat (buff, "INFO");
13126 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
13128 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
13129 strcat (buff, " | ");
13131 strcat (buff, _("<unknown>"));
13134 return buff;
13137 /* Display the contents of the version sections. */
13139 static bool
13140 process_version_sections (Filedata * filedata)
13142 Elf_Internal_Shdr * section;
13143 unsigned i;
13144 bool found = false;
13146 if (! do_version)
13147 return true;
13149 for (i = 0, section = filedata->section_headers;
13150 i < filedata->file_header.e_shnum;
13151 i++, section++)
13153 switch (section->sh_type)
13155 case SHT_GNU_verdef:
13157 Elf_External_Verdef * edefs;
13158 size_t idx;
13159 size_t cnt;
13160 char * endbuf;
13162 found = true;
13164 if (filedata->is_separate)
13165 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
13166 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
13167 section->sh_info),
13168 filedata->file_name,
13169 printable_section_name (filedata, section),
13170 section->sh_info);
13171 else
13172 printf (ngettext ("\nVersion definition section '%s' "
13173 "contains %u entry:\n",
13174 "\nVersion definition section '%s' "
13175 "contains %u entries:\n",
13176 section->sh_info),
13177 printable_section_name (filedata, section),
13178 section->sh_info);
13180 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
13181 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
13182 section->sh_offset, section->sh_link,
13183 printable_section_name_from_index (filedata, section->sh_link, NULL));
13185 edefs = (Elf_External_Verdef *)
13186 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
13187 _("version definition section"));
13188 if (!edefs)
13189 break;
13190 endbuf = (char *) edefs + section->sh_size;
13192 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
13194 char * vstart;
13195 Elf_External_Verdef * edef;
13196 Elf_Internal_Verdef ent;
13197 Elf_External_Verdaux * eaux;
13198 Elf_Internal_Verdaux aux;
13199 size_t isum;
13200 int j;
13202 vstart = ((char *) edefs) + idx;
13203 if (vstart + sizeof (*edef) > endbuf)
13204 break;
13206 edef = (Elf_External_Verdef *) vstart;
13208 ent.vd_version = BYTE_GET (edef->vd_version);
13209 ent.vd_flags = BYTE_GET (edef->vd_flags);
13210 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
13211 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
13212 ent.vd_hash = BYTE_GET (edef->vd_hash);
13213 ent.vd_aux = BYTE_GET (edef->vd_aux);
13214 ent.vd_next = BYTE_GET (edef->vd_next);
13216 printf (_(" %#06zx: Rev: %d Flags: %s"),
13217 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
13219 printf (_(" Index: %d Cnt: %d "),
13220 ent.vd_ndx, ent.vd_cnt);
13222 /* Check for overflow. */
13223 if (ent.vd_aux > (size_t) (endbuf - vstart))
13224 break;
13226 vstart += ent.vd_aux;
13228 if (vstart + sizeof (*eaux) > endbuf)
13229 break;
13230 eaux = (Elf_External_Verdaux *) vstart;
13232 aux.vda_name = BYTE_GET (eaux->vda_name);
13233 aux.vda_next = BYTE_GET (eaux->vda_next);
13235 if (valid_dynamic_name (filedata, aux.vda_name))
13236 printf (_("Name: %s\n"),
13237 get_dynamic_name (filedata, aux.vda_name));
13238 else
13239 printf (_("Name index: %ld\n"), aux.vda_name);
13241 isum = idx + ent.vd_aux;
13243 for (j = 1; j < ent.vd_cnt; j++)
13245 if (aux.vda_next < sizeof (*eaux)
13246 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
13248 warn (_("Invalid vda_next field of %lx\n"),
13249 aux.vda_next);
13250 j = ent.vd_cnt;
13251 break;
13253 /* Check for overflow. */
13254 if (aux.vda_next > (size_t) (endbuf - vstart))
13255 break;
13257 isum += aux.vda_next;
13258 vstart += aux.vda_next;
13260 if (vstart + sizeof (*eaux) > endbuf)
13261 break;
13262 eaux = (Elf_External_Verdaux *) vstart;
13264 aux.vda_name = BYTE_GET (eaux->vda_name);
13265 aux.vda_next = BYTE_GET (eaux->vda_next);
13267 if (valid_dynamic_name (filedata, aux.vda_name))
13268 printf (_(" %#06zx: Parent %d: %s\n"),
13269 isum, j,
13270 get_dynamic_name (filedata, aux.vda_name));
13271 else
13272 printf (_(" %#06zx: Parent %d, name index: %ld\n"),
13273 isum, j, aux.vda_name);
13276 if (j < ent.vd_cnt)
13277 printf (_(" Version def aux past end of section\n"));
13279 /* PR 17531:
13280 file: id:000001,src:000172+005151,op:splice,rep:2. */
13281 if (ent.vd_next < sizeof (*edef)
13282 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
13284 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
13285 cnt = section->sh_info;
13286 break;
13288 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
13289 break;
13291 idx += ent.vd_next;
13294 if (cnt < section->sh_info)
13295 printf (_(" Version definition past end of section\n"));
13297 free (edefs);
13299 break;
13301 case SHT_GNU_verneed:
13303 Elf_External_Verneed * eneed;
13304 size_t idx;
13305 size_t cnt;
13306 char * endbuf;
13308 found = true;
13310 if (filedata->is_separate)
13311 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
13312 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
13313 section->sh_info),
13314 filedata->file_name,
13315 printable_section_name (filedata, section),
13316 section->sh_info);
13317 else
13318 printf (ngettext ("\nVersion needs section '%s' "
13319 "contains %u entry:\n",
13320 "\nVersion needs section '%s' "
13321 "contains %u entries:\n",
13322 section->sh_info),
13323 printable_section_name (filedata, section),
13324 section->sh_info);
13326 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
13327 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
13328 section->sh_offset, section->sh_link,
13329 printable_section_name_from_index (filedata, section->sh_link, NULL));
13331 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
13332 section->sh_offset, 1,
13333 section->sh_size,
13334 _("Version Needs section"));
13335 if (!eneed)
13336 break;
13337 endbuf = (char *) eneed + section->sh_size;
13339 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
13341 Elf_External_Verneed * entry;
13342 Elf_Internal_Verneed ent;
13343 size_t isum;
13344 int j;
13345 char * vstart;
13347 vstart = ((char *) eneed) + idx;
13348 if (vstart + sizeof (*entry) > endbuf)
13349 break;
13351 entry = (Elf_External_Verneed *) vstart;
13353 ent.vn_version = BYTE_GET (entry->vn_version);
13354 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
13355 ent.vn_file = BYTE_GET (entry->vn_file);
13356 ent.vn_aux = BYTE_GET (entry->vn_aux);
13357 ent.vn_next = BYTE_GET (entry->vn_next);
13359 printf (_(" %#06zx: Version: %d"), idx, ent.vn_version);
13361 if (valid_dynamic_name (filedata, ent.vn_file))
13362 printf (_(" File: %s"),
13363 get_dynamic_name (filedata, ent.vn_file));
13364 else
13365 printf (_(" File: %lx"), ent.vn_file);
13367 printf (_(" Cnt: %d\n"), ent.vn_cnt);
13369 /* Check for overflow. */
13370 if (ent.vn_aux > (size_t) (endbuf - vstart))
13371 break;
13372 vstart += ent.vn_aux;
13374 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
13376 Elf_External_Vernaux * eaux;
13377 Elf_Internal_Vernaux aux;
13379 if (vstart + sizeof (*eaux) > endbuf)
13380 break;
13381 eaux = (Elf_External_Vernaux *) vstart;
13383 aux.vna_hash = BYTE_GET (eaux->vna_hash);
13384 aux.vna_flags = BYTE_GET (eaux->vna_flags);
13385 aux.vna_other = BYTE_GET (eaux->vna_other);
13386 aux.vna_name = BYTE_GET (eaux->vna_name);
13387 aux.vna_next = BYTE_GET (eaux->vna_next);
13389 if (valid_dynamic_name (filedata, aux.vna_name))
13390 printf (_(" %#06zx: Name: %s"),
13391 isum, get_dynamic_name (filedata, aux.vna_name));
13392 else
13393 printf (_(" %#06zx: Name index: %lx"),
13394 isum, aux.vna_name);
13396 printf (_(" Flags: %s Version: %d\n"),
13397 get_ver_flags (aux.vna_flags), aux.vna_other);
13399 if (aux.vna_next < sizeof (*eaux)
13400 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
13402 warn (_("Invalid vna_next field of %lx\n"),
13403 aux.vna_next);
13404 j = ent.vn_cnt;
13405 break;
13407 /* Check for overflow. */
13408 if (aux.vna_next > (size_t) (endbuf - vstart))
13409 break;
13410 isum += aux.vna_next;
13411 vstart += aux.vna_next;
13414 if (j < ent.vn_cnt)
13415 warn (_("Missing Version Needs auxiliary information\n"));
13417 if (ent.vn_next < sizeof (*entry)
13418 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
13420 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
13421 cnt = section->sh_info;
13422 break;
13424 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
13425 break;
13426 idx += ent.vn_next;
13429 if (cnt < section->sh_info)
13430 warn (_("Missing Version Needs information\n"));
13432 free (eneed);
13434 break;
13436 case SHT_GNU_versym:
13438 Elf_Internal_Shdr * link_section;
13439 uint64_t total;
13440 unsigned int cnt;
13441 unsigned char * edata;
13442 unsigned short * data;
13443 char * strtab;
13444 Elf_Internal_Sym * symbols;
13445 Elf_Internal_Shdr * string_sec;
13446 uint64_t num_syms;
13447 uint64_t off;
13449 if (section->sh_link >= filedata->file_header.e_shnum)
13450 break;
13452 link_section = filedata->section_headers + section->sh_link;
13453 total = section->sh_size / sizeof (Elf_External_Versym);
13455 if (link_section->sh_link >= filedata->file_header.e_shnum)
13456 break;
13458 found = true;
13460 symbols = get_elf_symbols (filedata, link_section, & num_syms);
13461 if (symbols == NULL)
13462 break;
13464 string_sec = filedata->section_headers + link_section->sh_link;
13466 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
13467 string_sec->sh_size,
13468 _("version string table"));
13469 if (!strtab)
13471 free (symbols);
13472 break;
13475 if (filedata->is_separate)
13476 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entry:\n",
13477 "\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entries:\n",
13478 total),
13479 filedata->file_name,
13480 printable_section_name (filedata, section),
13481 total);
13482 else
13483 printf (ngettext ("\nVersion symbols section '%s' "
13484 "contains %" PRIu64 " entry:\n",
13485 "\nVersion symbols section '%s' "
13486 "contains %" PRIu64 " entries:\n",
13487 total),
13488 printable_section_name (filedata, section),
13489 total);
13491 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
13492 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
13493 section->sh_offset, section->sh_link,
13494 printable_section_name (filedata, link_section));
13496 off = offset_from_vma (filedata,
13497 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
13498 total * sizeof (short));
13499 edata = (unsigned char *) get_data (NULL, filedata, off,
13500 sizeof (short), total,
13501 _("version symbol data"));
13502 if (!edata)
13504 free (strtab);
13505 free (symbols);
13506 break;
13509 data = (short unsigned int *) cmalloc (total, sizeof (short));
13511 for (cnt = total; cnt --;)
13512 data[cnt] = byte_get (edata + cnt * sizeof (short),
13513 sizeof (short));
13515 free (edata);
13517 for (cnt = 0; cnt < total; cnt += 4)
13519 int j, nn;
13520 char *name;
13521 char *invalid = _("*invalid*");
13523 printf (" %03x:", cnt);
13525 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
13526 switch (data[cnt + j])
13528 case 0:
13529 fputs (_(" 0 (*local*) "), stdout);
13530 break;
13532 case 1:
13533 fputs (_(" 1 (*global*) "), stdout);
13534 break;
13536 default:
13537 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
13538 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
13540 /* If this index value is greater than the size of the symbols
13541 array, break to avoid an out-of-bounds read. */
13542 if (cnt + j >= num_syms)
13544 warn (_("invalid index into symbol array\n"));
13545 break;
13548 name = NULL;
13549 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
13551 Elf_Internal_Verneed ivn;
13552 uint64_t offset;
13554 offset = offset_from_vma
13555 (filedata,
13556 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
13557 sizeof (Elf_External_Verneed));
13561 Elf_Internal_Vernaux ivna;
13562 Elf_External_Verneed evn;
13563 Elf_External_Vernaux evna;
13564 uint64_t a_off;
13566 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
13567 _("version need")) == NULL)
13568 break;
13570 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13571 ivn.vn_next = BYTE_GET (evn.vn_next);
13573 a_off = offset + ivn.vn_aux;
13577 if (get_data (&evna, filedata, a_off, sizeof (evna),
13578 1, _("version need aux (2)")) == NULL)
13580 ivna.vna_next = 0;
13581 ivna.vna_other = 0;
13583 else
13585 ivna.vna_next = BYTE_GET (evna.vna_next);
13586 ivna.vna_other = BYTE_GET (evna.vna_other);
13589 a_off += ivna.vna_next;
13591 while (ivna.vna_other != data[cnt + j]
13592 && ivna.vna_next != 0);
13594 if (ivna.vna_other == data[cnt + j])
13596 ivna.vna_name = BYTE_GET (evna.vna_name);
13598 if (ivna.vna_name >= string_sec->sh_size)
13599 name = invalid;
13600 else
13601 name = strtab + ivna.vna_name;
13602 break;
13605 offset += ivn.vn_next;
13607 while (ivn.vn_next);
13610 if (data[cnt + j] != 0x8001
13611 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
13613 Elf_Internal_Verdef ivd;
13614 Elf_External_Verdef evd;
13615 uint64_t offset;
13617 offset = offset_from_vma
13618 (filedata,
13619 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
13620 sizeof evd);
13624 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
13625 _("version def")) == NULL)
13627 ivd.vd_next = 0;
13628 /* PR 17531: file: 046-1082287-0.004. */
13629 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
13630 break;
13632 else
13634 ivd.vd_next = BYTE_GET (evd.vd_next);
13635 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13638 offset += ivd.vd_next;
13640 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
13641 && ivd.vd_next != 0);
13643 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
13645 Elf_External_Verdaux evda;
13646 Elf_Internal_Verdaux ivda;
13648 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13650 if (get_data (&evda, filedata,
13651 offset - ivd.vd_next + ivd.vd_aux,
13652 sizeof (evda), 1,
13653 _("version def aux")) == NULL)
13654 break;
13656 ivda.vda_name = BYTE_GET (evda.vda_name);
13658 if (ivda.vda_name >= string_sec->sh_size)
13659 name = invalid;
13660 else if (name != NULL && name != invalid)
13661 name = _("*both*");
13662 else
13663 name = strtab + ivda.vda_name;
13666 if (name != NULL)
13667 nn += printf ("(%s%-*s",
13668 name,
13669 12 - (int) strlen (name),
13670 ")");
13672 if (nn < 18)
13673 printf ("%*c", 18 - nn, ' ');
13676 putchar ('\n');
13679 free (data);
13680 free (strtab);
13681 free (symbols);
13683 break;
13685 default:
13686 break;
13690 if (! found)
13692 if (filedata->is_separate)
13693 printf (_("\nNo version information found in linked file '%s'.\n"),
13694 filedata->file_name);
13695 else
13696 printf (_("\nNo version information found in this file.\n"));
13699 return true;
13702 static const char *
13703 get_symbol_binding (Filedata * filedata, unsigned int binding)
13705 static char buff[64];
13707 switch (binding)
13709 case STB_LOCAL: return "LOCAL";
13710 case STB_GLOBAL: return "GLOBAL";
13711 case STB_WEAK: return "WEAK";
13712 default:
13713 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
13714 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
13715 binding);
13716 else if (binding >= STB_LOOS && binding <= STB_HIOS)
13718 if (binding == STB_GNU_UNIQUE
13719 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
13720 return "UNIQUE";
13721 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
13723 else
13724 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
13725 return buff;
13729 static const char *
13730 get_symbol_type (Filedata * filedata, unsigned int type)
13732 static char buff[64];
13734 switch (type)
13736 case STT_NOTYPE: return "NOTYPE";
13737 case STT_OBJECT: return "OBJECT";
13738 case STT_FUNC: return "FUNC";
13739 case STT_SECTION: return "SECTION";
13740 case STT_FILE: return "FILE";
13741 case STT_COMMON: return "COMMON";
13742 case STT_TLS: return "TLS";
13743 case STT_RELC: return "RELC";
13744 case STT_SRELC: return "SRELC";
13745 default:
13746 if (type >= STT_LOPROC && type <= STT_HIPROC)
13748 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
13749 return "THUMB_FUNC";
13751 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
13752 return "REGISTER";
13754 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
13755 return "PARISC_MILLI";
13757 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
13759 else if (type >= STT_LOOS && type <= STT_HIOS)
13761 if (filedata->file_header.e_machine == EM_PARISC)
13763 if (type == STT_HP_OPAQUE)
13764 return "HP_OPAQUE";
13765 if (type == STT_HP_STUB)
13766 return "HP_STUB";
13769 if (type == STT_GNU_IFUNC
13770 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
13771 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
13772 return "IFUNC";
13774 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
13776 else
13777 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
13778 return buff;
13782 static const char *
13783 get_symbol_visibility (unsigned int visibility)
13785 switch (visibility)
13787 case STV_DEFAULT: return "DEFAULT";
13788 case STV_INTERNAL: return "INTERNAL";
13789 case STV_HIDDEN: return "HIDDEN";
13790 case STV_PROTECTED: return "PROTECTED";
13791 default:
13792 error (_("Unrecognized visibility value: %u\n"), visibility);
13793 return _("<unknown>");
13797 static const char *
13798 get_alpha_symbol_other (unsigned int other)
13800 switch (other)
13802 case STO_ALPHA_NOPV: return "NOPV";
13803 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
13804 default:
13805 error (_("Unrecognized alpha specific other value: %u\n"), other);
13806 return _("<unknown>");
13810 static const char *
13811 get_solaris_symbol_visibility (unsigned int visibility)
13813 switch (visibility)
13815 case 4: return "EXPORTED";
13816 case 5: return "SINGLETON";
13817 case 6: return "ELIMINATE";
13818 default: return get_symbol_visibility (visibility);
13822 static const char *
13823 get_aarch64_symbol_other (unsigned int other)
13825 static char buf[32];
13827 if (other & STO_AARCH64_VARIANT_PCS)
13829 other &= ~STO_AARCH64_VARIANT_PCS;
13830 if (other == 0)
13831 return "VARIANT_PCS";
13832 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
13833 return buf;
13835 return NULL;
13838 static const char *
13839 get_mips_symbol_other (unsigned int other)
13841 switch (other)
13843 case STO_OPTIONAL: return "OPTIONAL";
13844 case STO_MIPS_PLT: return "MIPS PLT";
13845 case STO_MIPS_PIC: return "MIPS PIC";
13846 case STO_MICROMIPS: return "MICROMIPS";
13847 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
13848 case STO_MIPS16: return "MIPS16";
13849 default: return NULL;
13853 static const char *
13854 get_ia64_symbol_other (Filedata * filedata, unsigned int other)
13856 if (is_ia64_vms (filedata))
13858 static char res[32];
13860 res[0] = 0;
13862 /* Function types is for images and .STB files only. */
13863 switch (filedata->file_header.e_type)
13865 case ET_DYN:
13866 case ET_EXEC:
13867 switch (VMS_ST_FUNC_TYPE (other))
13869 case VMS_SFT_CODE_ADDR:
13870 strcat (res, " CA");
13871 break;
13872 case VMS_SFT_SYMV_IDX:
13873 strcat (res, " VEC");
13874 break;
13875 case VMS_SFT_FD:
13876 strcat (res, " FD");
13877 break;
13878 case VMS_SFT_RESERVE:
13879 strcat (res, " RSV");
13880 break;
13881 default:
13882 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
13883 VMS_ST_FUNC_TYPE (other));
13884 strcat (res, " <unknown>");
13885 break;
13887 break;
13888 default:
13889 break;
13891 switch (VMS_ST_LINKAGE (other))
13893 case VMS_STL_IGNORE:
13894 strcat (res, " IGN");
13895 break;
13896 case VMS_STL_RESERVE:
13897 strcat (res, " RSV");
13898 break;
13899 case VMS_STL_STD:
13900 strcat (res, " STD");
13901 break;
13902 case VMS_STL_LNK:
13903 strcat (res, " LNK");
13904 break;
13905 default:
13906 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
13907 VMS_ST_LINKAGE (other));
13908 strcat (res, " <unknown>");
13909 break;
13912 if (res[0] != 0)
13913 return res + 1;
13914 else
13915 return res;
13917 return NULL;
13920 static const char *
13921 get_ppc64_symbol_other (unsigned int other)
13923 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
13924 return NULL;
13926 other >>= STO_PPC64_LOCAL_BIT;
13927 if (other <= 6)
13929 static char buf[64];
13930 if (other >= 2)
13931 other = ppc64_decode_local_entry (other);
13932 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
13933 return buf;
13935 return NULL;
13938 static const char *
13939 get_riscv_symbol_other (unsigned int other)
13941 static char buf[32];
13942 buf[0] = 0;
13944 if (other & STO_RISCV_VARIANT_CC)
13946 strcat (buf, _(" VARIANT_CC"));
13947 other &= ~STO_RISCV_VARIANT_CC;
13950 if (other != 0)
13951 snprintf (buf, sizeof buf, " %x", other);
13954 if (buf[0] != 0)
13955 return buf + 1;
13956 else
13957 return buf;
13960 static const char *
13961 get_symbol_other (Filedata * filedata, unsigned int other)
13963 const char * result = NULL;
13964 static char buff [64];
13966 if (other == 0)
13967 return "";
13969 switch (filedata->file_header.e_machine)
13971 case EM_ALPHA:
13972 result = get_alpha_symbol_other (other);
13973 break;
13974 case EM_AARCH64:
13975 result = get_aarch64_symbol_other (other);
13976 break;
13977 case EM_MIPS:
13978 result = get_mips_symbol_other (other);
13979 break;
13980 case EM_IA_64:
13981 result = get_ia64_symbol_other (filedata, other);
13982 break;
13983 case EM_PPC64:
13984 result = get_ppc64_symbol_other (other);
13985 break;
13986 case EM_RISCV:
13987 result = get_riscv_symbol_other (other);
13988 break;
13989 default:
13990 result = NULL;
13991 break;
13994 if (result)
13995 return result;
13997 snprintf (buff, sizeof buff, _("<other>: %x"), other);
13998 return buff;
14001 static const char *
14002 get_symbol_version_string (Filedata *filedata,
14003 bool is_dynsym,
14004 const char *strtab,
14005 size_t strtab_size,
14006 unsigned int si,
14007 Elf_Internal_Sym *psym,
14008 enum versioned_symbol_info *sym_info,
14009 unsigned short *vna_other)
14011 unsigned char data[2];
14012 unsigned short vers_data;
14013 uint64_t offset;
14014 unsigned short max_vd_ndx;
14016 if (!is_dynsym
14017 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
14018 return NULL;
14020 offset = offset_from_vma (filedata,
14021 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
14022 sizeof data + si * sizeof (vers_data));
14024 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
14025 sizeof (data), 1, _("version data")) == NULL)
14026 return NULL;
14028 vers_data = byte_get (data, 2);
14030 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
14031 return NULL;
14033 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
14034 max_vd_ndx = 0;
14036 /* Usually we'd only see verdef for defined symbols, and verneed for
14037 undefined symbols. However, symbols defined by the linker in
14038 .dynbss for variables copied from a shared library in order to
14039 avoid text relocations are defined yet have verneed. We could
14040 use a heuristic to detect the special case, for example, check
14041 for verneed first on symbols defined in SHT_NOBITS sections, but
14042 it is simpler and more reliable to just look for both verdef and
14043 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
14045 if (psym->st_shndx != SHN_UNDEF
14046 && vers_data != 0x8001
14047 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
14049 Elf_Internal_Verdef ivd;
14050 Elf_Internal_Verdaux ivda;
14051 Elf_External_Verdaux evda;
14052 uint64_t off;
14054 off = offset_from_vma (filedata,
14055 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
14056 sizeof (Elf_External_Verdef));
14060 Elf_External_Verdef evd;
14062 if (get_data (&evd, filedata, off, sizeof (evd), 1,
14063 _("version def")) == NULL)
14065 ivd.vd_ndx = 0;
14066 ivd.vd_aux = 0;
14067 ivd.vd_next = 0;
14068 ivd.vd_flags = 0;
14070 else
14072 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
14073 ivd.vd_aux = BYTE_GET (evd.vd_aux);
14074 ivd.vd_next = BYTE_GET (evd.vd_next);
14075 ivd.vd_flags = BYTE_GET (evd.vd_flags);
14078 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
14079 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
14081 off += ivd.vd_next;
14083 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
14085 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
14087 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
14088 return NULL;
14090 off -= ivd.vd_next;
14091 off += ivd.vd_aux;
14093 if (get_data (&evda, filedata, off, sizeof (evda), 1,
14094 _("version def aux")) != NULL)
14096 ivda.vda_name = BYTE_GET (evda.vda_name);
14098 if (psym->st_name != ivda.vda_name)
14099 return (ivda.vda_name < strtab_size
14100 ? strtab + ivda.vda_name : _("<corrupt>"));
14105 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
14107 Elf_External_Verneed evn;
14108 Elf_Internal_Verneed ivn;
14109 Elf_Internal_Vernaux ivna;
14111 offset = offset_from_vma (filedata,
14112 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
14113 sizeof evn);
14116 uint64_t vna_off;
14118 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
14119 _("version need")) == NULL)
14121 ivna.vna_next = 0;
14122 ivna.vna_other = 0;
14123 ivna.vna_name = 0;
14124 break;
14127 ivn.vn_aux = BYTE_GET (evn.vn_aux);
14128 ivn.vn_next = BYTE_GET (evn.vn_next);
14130 vna_off = offset + ivn.vn_aux;
14134 Elf_External_Vernaux evna;
14136 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
14137 _("version need aux (3)")) == NULL)
14139 ivna.vna_next = 0;
14140 ivna.vna_other = 0;
14141 ivna.vna_name = 0;
14143 else
14145 ivna.vna_other = BYTE_GET (evna.vna_other);
14146 ivna.vna_next = BYTE_GET (evna.vna_next);
14147 ivna.vna_name = BYTE_GET (evna.vna_name);
14150 vna_off += ivna.vna_next;
14152 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
14154 if (ivna.vna_other == vers_data)
14155 break;
14157 offset += ivn.vn_next;
14159 while (ivn.vn_next != 0);
14161 if (ivna.vna_other == vers_data)
14163 *sym_info = symbol_undefined;
14164 *vna_other = ivna.vna_other;
14165 return (ivna.vna_name < strtab_size
14166 ? strtab + ivna.vna_name : _("<corrupt>"));
14168 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
14169 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
14170 return _("<corrupt>");
14172 return NULL;
14175 /* Display a symbol size on stdout. Format is based on --sym-base setting. */
14177 static unsigned int
14178 print_symbol_size (uint64_t vma, int base)
14180 switch (base)
14182 case 8:
14183 return print_vma (vma, OCTAL_5);
14185 case 10:
14186 return print_vma (vma, UNSIGNED_5);
14188 case 16:
14189 return print_vma (vma, PREFIX_HEX_5);
14191 case 0:
14192 default:
14193 return print_vma (vma, DEC_5);
14197 /* Print information on a single symbol. */
14199 static void
14200 print_symbol (Filedata * filedata,
14201 uint64_t symbol_index,
14202 Elf_Internal_Sym * symtab,
14203 Elf_Internal_Shdr * section,
14204 char * strtab,
14205 size_t strtab_size)
14207 const char *version_string;
14208 enum versioned_symbol_info sym_info;
14209 unsigned short vna_other;
14210 const char * sstr;
14211 Elf_Internal_Sym *psym = symtab + symbol_index;
14213 /* FIXME: We should have a table of field widths,
14214 rather than using hard coded constants. */
14215 printf ("%6" PRId64 ": ", symbol_index);
14216 print_vma (psym->st_value, LONG_HEX);
14217 putchar (' ');
14218 print_symbol_size (psym->st_size, sym_base);
14219 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
14220 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
14221 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
14222 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
14223 else
14225 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
14227 printf (" %-7s", get_symbol_visibility (vis));
14229 /* Check to see if any other bits in the st_other field are set.
14230 FIXME: Displaying this information here disrupts the layout
14231 of the table being generated. */
14232 if (psym->st_other ^ vis)
14233 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
14236 bool is_special;
14238 sstr = printable_section_name_from_index (filedata, psym->st_shndx, & is_special);
14240 /* Print the symbol's section index. If the index is special
14241 then print the index's name rather than its number. */
14242 if (is_special)
14244 int printed;
14246 /* Special case: If there are no section headers, and the printable
14247 name is "<section 0x...." then just display the section number
14248 as a decimal. This happens when objcopy --strip -section-headers
14249 is used. */
14250 if (filedata->file_header.e_shnum == 0 && startswith (sstr, "<section"))
14251 printed = printf (" %4d ", psym->st_shndx);
14252 else
14253 printed = printf (" %4s ", sstr);
14255 if (extra_sym_info && printed < 16)
14256 printf ("%*s", 16 - printed, "");
14258 else
14260 printf (" %4u ", psym->st_shndx);
14262 if (extra_sym_info)
14264 /* Display the section name referenced by the section index. */
14265 int printed = printf ("(%s) ", sstr);
14266 if (printed < 10)
14267 printf ("%*s", 10 - printed, "");
14271 /* Get the symbol's name. For section symbols without a
14272 specific name use the (already computed) section name. */
14273 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
14274 && section_index_real (filedata, psym->st_shndx)
14275 && psym->st_name == 0)
14279 else
14281 bool is_valid;
14283 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
14284 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
14287 version_string
14288 = get_symbol_version_string (filedata,
14289 (section == NULL
14290 || section->sh_type == SHT_DYNSYM),
14291 strtab, strtab_size, symbol_index,
14292 psym, &sym_info, &vna_other);
14294 int len_avail = 21;
14295 if (! do_wide && version_string != NULL)
14297 char buffer[16];
14299 len_avail -= 1 + strlen (version_string);
14301 if (sym_info == symbol_undefined)
14302 len_avail -= sprintf (buffer," (%d)", vna_other);
14303 else if (sym_info != symbol_hidden)
14304 len_avail -= 1;
14307 print_symbol_name (len_avail, sstr);
14309 if (version_string)
14311 if (sym_info == symbol_undefined)
14312 printf ("@%s (%d)", version_string, vna_other);
14313 else
14314 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
14315 version_string);
14318 putchar ('\n');
14320 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
14321 && section != NULL
14322 && symbol_index >= section->sh_info
14323 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
14324 && filedata->file_header.e_machine != EM_MIPS
14325 /* Solaris binaries have been found to violate this requirement as
14326 well. Not sure if this is a bug or an ABI requirement. */
14327 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
14328 warn (_("local symbol %" PRIu64 " found at index >= %s's sh_info value of %u\n"),
14329 symbol_index, printable_section_name (filedata, section), section->sh_info);
14332 static const char *
14333 get_lto_kind (unsigned int kind)
14335 switch (kind)
14337 case 0: return "DEF";
14338 case 1: return "WEAKDEF";
14339 case 2: return "UNDEF";
14340 case 3: return "WEAKUNDEF";
14341 case 4: return "COMMON";
14342 default:
14343 break;
14346 static char buffer[30];
14347 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
14348 sprintf (buffer, "<unknown: %u>", kind);
14349 return buffer;
14352 static const char *
14353 get_lto_visibility (unsigned int visibility)
14355 switch (visibility)
14357 case 0: return "DEFAULT";
14358 case 1: return "PROTECTED";
14359 case 2: return "INTERNAL";
14360 case 3: return "HIDDEN";
14361 default:
14362 break;
14365 static char buffer[30];
14366 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
14367 sprintf (buffer, "<unknown: %u>", visibility);
14368 return buffer;
14371 static const char *
14372 get_lto_sym_type (unsigned int sym_type)
14374 switch (sym_type)
14376 case 0: return "UNKNOWN";
14377 case 1: return "FUNCTION";
14378 case 2: return "VARIABLE";
14379 default:
14380 break;
14383 static char buffer[30];
14384 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
14385 sprintf (buffer, "<unknown: %u>", sym_type);
14386 return buffer;
14389 /* Display an LTO format symbol table.
14390 FIXME: The format of LTO symbol tables is not formalized.
14391 So this code could need changing in the future. */
14393 static bool
14394 display_lto_symtab (Filedata * filedata,
14395 Elf_Internal_Shdr * section)
14397 if (section->sh_size == 0)
14399 if (filedata->is_separate)
14400 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
14401 printable_section_name (filedata, section),
14402 filedata->file_name);
14403 else
14404 printf (_("\nLTO Symbol table '%s' is empty!\n"),
14405 printable_section_name (filedata, section));
14407 return true;
14410 if (section->sh_size > filedata->file_size)
14412 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
14413 printable_section_name (filedata, section),
14414 section->sh_size);
14415 return false;
14418 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
14419 section->sh_size, 1, _("LTO symbols"));
14420 if (alloced_data == NULL)
14421 return false;
14423 /* Look for extended data for the symbol table. */
14424 void * ext_data_orig = NULL;
14425 char * ext_data = NULL;
14426 char * ext_data_end = NULL;
14427 char *ext_name = xasprintf (".gnu.lto_.ext_symtab.%s",
14428 (section_name (filedata, section)
14429 + sizeof (".gnu.lto_.symtab.")));
14430 Elf_Internal_Shdr *ext = find_section (filedata, ext_name);
14431 if (ext != NULL)
14433 if (ext->sh_size < 3)
14434 error (_("LTO Symbol extension table '%s' is empty!\n"),
14435 printable_section_name (filedata, ext));
14436 else
14438 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
14439 ext->sh_size, 1,
14440 _("LTO ext symbol data"));
14441 if (ext_data != NULL)
14443 ext_data_end = ext_data + ext->sh_size;
14444 if (* ext_data++ != 1)
14445 error (_("Unexpected version number in symbol extension table\n"));
14450 const unsigned char * data = (const unsigned char *) alloced_data;
14451 const unsigned char * end = data + section->sh_size;
14453 if (filedata->is_separate)
14454 printf (_("\nIn linked file '%s': "), filedata->file_name);
14455 else
14456 printf ("\n");
14458 if (ext_data_orig != NULL)
14460 if (do_wide)
14461 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
14462 printable_section_name (filedata, section),
14463 printable_section_name (filedata, ext));
14464 else
14466 printf (_("LTO Symbol table '%s'\n"),
14467 printable_section_name (filedata, section));
14468 printf (_(" and extension table '%s' contain:\n"),
14469 printable_section_name (filedata, ext));
14472 else
14473 printf (_("LTO Symbol table '%s' contains:\n"),
14474 printable_section_name (filedata, section));
14476 /* FIXME: Add a wide version. */
14477 if (ext_data_orig != NULL)
14478 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
14479 else
14480 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
14482 /* FIXME: We do not handle style prefixes. */
14484 while (data < end)
14486 const unsigned char * sym_name = data;
14487 data += strnlen ((const char *) sym_name, end - data) + 1;
14488 if (data >= end)
14489 goto fail;
14491 const unsigned char * comdat_key = data;
14492 data += strnlen ((const char *) comdat_key, end - data) + 1;
14493 if (data >= end)
14494 goto fail;
14496 if (data + 2 + 8 + 4 > end)
14497 goto fail;
14499 unsigned int kind = *data++;
14500 unsigned int visibility = *data++;
14502 uint64_t size = byte_get (data, 8);
14503 data += 8;
14505 uint64_t slot = byte_get (data, 4);
14506 data += 4;
14508 if (ext_data != NULL)
14510 if (ext_data < (ext_data_end - 1))
14512 unsigned int sym_type = * ext_data ++;
14513 unsigned int sec_kind = * ext_data ++;
14515 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " %9s %08x _",
14516 * comdat_key == 0 ? "-" : (char *) comdat_key,
14517 get_lto_kind (kind),
14518 get_lto_visibility (visibility),
14519 size,
14520 slot,
14521 get_lto_sym_type (sym_type),
14522 sec_kind);
14523 print_symbol_name (6, (const char *) sym_name);
14525 else
14527 error (_("Ran out of LTO symbol extension data\n"));
14528 ext_data = NULL;
14529 /* FIXME: return FAIL result ? */
14532 else
14534 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " _",
14535 * comdat_key == 0 ? "-" : (char *) comdat_key,
14536 get_lto_kind (kind),
14537 get_lto_visibility (visibility),
14538 size,
14539 slot);
14540 print_symbol_name (21, (const char *) sym_name);
14542 putchar ('\n');
14545 if (ext_data != NULL && ext_data < ext_data_end)
14547 error (_("Data remains in the LTO symbol extension table\n"));
14548 goto fail;
14551 free (alloced_data);
14552 free (ext_data_orig);
14553 free (ext_name);
14554 return true;
14556 fail:
14557 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
14558 free (alloced_data);
14559 free (ext_data_orig);
14560 free (ext_name);
14561 return false;
14564 /* Display LTO symbol tables. */
14566 static bool
14567 process_lto_symbol_tables (Filedata * filedata)
14569 Elf_Internal_Shdr * section;
14570 unsigned int i;
14571 bool res = true;
14573 if (!do_lto_syms)
14574 return true;
14576 if (filedata->section_headers == NULL)
14577 return true;
14579 for (i = 0, section = filedata->section_headers;
14580 i < filedata->file_header.e_shnum;
14581 i++, section++)
14582 if (section_name_valid (filedata, section)
14583 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
14584 res &= display_lto_symtab (filedata, section);
14586 return res;
14589 static void
14590 print_symbol_table_heading (void)
14592 /* FIXME: We should store the size of each field in the display in a table and
14593 then use the values inside print_symbol(), instead of that function using
14594 hard coded constants. */
14595 if (is_32bit_elf)
14597 if (extra_sym_info)
14599 printf (_(" Num: Value Size Type Bind Vis+Other Ndx(SecName) Name [+ Version Info]\n"));
14600 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |---8--| |----13.....| |........... */
14601 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 (.text) get_sections */
14603 else if (do_wide)
14605 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14606 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |-4| |........... */
14607 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 get_sections */
14609 else
14611 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14612 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |-4| |------------29-------------| */
14613 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 get_sections */
14616 else
14618 if (extra_sym_info)
14620 printf (_(" Num: Value Size Type Bind Vis+Other Ndx(SecName) Name [+ Version Info]\n"));
14621 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-------14---| |..... */
14622 /* eg: 2: 0000000000000000 0 FUNC LOCAL DEFAULT 1 (.text) .very_long_function_name */
14625 else if (do_wide)
14627 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14628 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-4| |........... */
14629 /* eg: 5: 0000000000000000 14 FUNC LOCAL DEFAULT 1 very_long_function_name */
14631 else
14633 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14634 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-4| |--------21---------| */
14635 /* eg: 5: 0000000000000000 14 FUNC LOCAL DEFAULT 1 very_long_functi[...] */
14640 static bool
14641 dump_symbol_section (Elf_Internal_Shdr * section,
14642 Filedata * filedata)
14644 if (section->sh_entsize == 0)
14646 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
14647 printable_section_name (filedata, section));
14648 return false;
14651 uint64_t num_syms = section->sh_size / section->sh_entsize;
14653 if (filedata->is_separate)
14654 printf (ngettext ("\nIn linked file '%s' symbol section '%s'"
14655 " contains %" PRIu64 " entry:\n",
14656 "\nIn linked file '%s' symbol section '%s'"
14657 " contains %" PRIu64 " entries:\n",
14658 num_syms),
14659 filedata->file_name,
14660 printable_section_name (filedata, section),
14661 num_syms);
14662 else
14663 printf (ngettext ("\nSymbol table '%s' contains %" PRIu64
14664 " entry:\n",
14665 "\nSymbol table '%s' contains %" PRIu64
14666 " entries:\n",
14667 num_syms),
14668 printable_section_name (filedata, section),
14669 num_syms);
14671 print_symbol_table_heading ();
14673 Elf_Internal_Sym * symtab = get_elf_symbols (filedata, section, & num_syms);
14674 if (symtab == NULL)
14675 /* An error message will have already been displayed. */
14676 return false;
14678 char * strtab = NULL;
14679 uint64_t strtab_size = 0;
14681 if (section->sh_link == filedata->file_header.e_shstrndx)
14683 strtab = filedata->string_table;
14684 strtab_size = filedata->string_table_length;
14686 else if (section->sh_link < filedata->file_header.e_shnum)
14688 Elf_Internal_Shdr * string_sec;
14690 string_sec = filedata->section_headers + section->sh_link;
14692 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
14693 1, string_sec->sh_size,
14694 _("string table"));
14695 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
14698 uint64_t si;
14700 for (si = 0; si < num_syms; si++)
14701 print_symbol (filedata, si, symtab, section, strtab, strtab_size);
14703 free (symtab);
14705 if (strtab != filedata->string_table)
14706 free (strtab);
14708 return true;
14711 /* Dump the symbol table. */
14713 static bool
14714 process_symbol_table (Filedata * filedata)
14716 Elf_Internal_Shdr * section;
14718 if (!do_syms && !do_dyn_syms && !do_histogram)
14719 return true;
14721 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
14722 && do_syms
14723 && do_using_dynamic
14724 && filedata->dynamic_strings != NULL
14725 && filedata->dynamic_symbols != NULL)
14727 uint64_t si;
14729 if (filedata->is_separate)
14731 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table"
14732 " contains %" PRIu64 " entry:\n",
14733 "\nIn linked file '%s' the dynamic symbol table"
14734 " contains %" PRIu64 " entries:\n",
14735 filedata->num_dynamic_syms),
14736 filedata->file_name,
14737 filedata->num_dynamic_syms);
14739 else
14741 printf (ngettext ("\nSymbol table for image contains %" PRIu64
14742 " entry:\n",
14743 "\nSymbol table for image contains %" PRIu64
14744 " entries:\n",
14745 filedata->num_dynamic_syms),
14746 filedata->num_dynamic_syms);
14749 print_symbol_table_heading ();
14751 for (si = 0; si < filedata->num_dynamic_syms; si++)
14752 print_symbol (filedata, si, filedata->dynamic_symbols, NULL,
14753 filedata->dynamic_strings,
14754 filedata->dynamic_strings_length);
14756 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
14757 && filedata->section_headers != NULL)
14759 unsigned int i;
14761 for (i = 0, section = filedata->section_headers;
14762 i < filedata->file_header.e_shnum;
14763 i++, section++)
14765 if ((section->sh_type != SHT_SYMTAB
14766 && section->sh_type != SHT_DYNSYM)
14767 || (!do_syms
14768 && section->sh_type == SHT_SYMTAB))
14769 continue;
14771 dump_symbol_section (section, filedata);
14774 else if (do_syms)
14775 printf
14776 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
14778 if (do_histogram && filedata->buckets != NULL)
14780 uint64_t *lengths;
14781 uint64_t *counts;
14782 uint64_t hn;
14783 uint64_t si;
14784 uint64_t maxlength = 0;
14785 uint64_t nzero_counts = 0;
14786 uint64_t nsyms = 0;
14787 char *visited;
14789 printf (ngettext ("\nHistogram for bucket list length "
14790 "(total of %" PRIu64 " bucket):\n",
14791 "\nHistogram for bucket list length "
14792 "(total of %" PRIu64 " buckets):\n",
14793 filedata->nbuckets),
14794 filedata->nbuckets);
14796 lengths = calloc (filedata->nbuckets, sizeof (*lengths));
14797 if (lengths == NULL)
14799 error (_("Out of memory allocating space for histogram buckets\n"));
14800 goto err_out;
14802 visited = xcmalloc (filedata->nchains, 1);
14803 memset (visited, 0, filedata->nchains);
14805 printf (_(" Length Number %% of total Coverage\n"));
14806 for (hn = 0; hn < filedata->nbuckets; ++hn)
14808 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
14810 ++nsyms;
14811 if (maxlength < ++lengths[hn])
14812 ++maxlength;
14813 if (si >= filedata->nchains || visited[si])
14815 error (_("histogram chain is corrupt\n"));
14816 break;
14818 visited[si] = 1;
14821 free (visited);
14823 counts = calloc (maxlength + 1, sizeof (*counts));
14824 if (counts == NULL)
14826 free (lengths);
14827 error (_("Out of memory allocating space for histogram counts\n"));
14828 goto err_out;
14831 for (hn = 0; hn < filedata->nbuckets; ++hn)
14832 ++counts[lengths[hn]];
14834 if (filedata->nbuckets > 0)
14836 uint64_t i;
14837 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
14838 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
14839 for (i = 1; i <= maxlength; ++i)
14841 nzero_counts += counts[i] * i;
14842 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
14843 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
14844 (nzero_counts * 100.0) / nsyms);
14848 free (counts);
14849 free (lengths);
14852 free (filedata->buckets);
14853 filedata->buckets = NULL;
14854 filedata->nbuckets = 0;
14855 free (filedata->chains);
14856 filedata->chains = NULL;
14858 if (do_histogram && filedata->gnubuckets != NULL)
14860 uint64_t *lengths;
14861 uint64_t *counts;
14862 uint64_t hn;
14863 uint64_t maxlength = 0;
14864 uint64_t nzero_counts = 0;
14865 uint64_t nsyms = 0;
14867 printf (ngettext ("\nHistogram for `%s' bucket list length "
14868 "(total of %" PRIu64 " bucket):\n",
14869 "\nHistogram for `%s' bucket list length "
14870 "(total of %" PRIu64 " buckets):\n",
14871 filedata->ngnubuckets),
14872 GNU_HASH_SECTION_NAME (filedata),
14873 filedata->ngnubuckets);
14875 lengths = calloc (filedata->ngnubuckets, sizeof (*lengths));
14876 if (lengths == NULL)
14878 error (_("Out of memory allocating space for gnu histogram buckets\n"));
14879 goto err_out;
14882 printf (_(" Length Number %% of total Coverage\n"));
14884 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
14885 if (filedata->gnubuckets[hn] != 0)
14887 uint64_t off, length = 1;
14889 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
14890 /* PR 17531 file: 010-77222-0.004. */
14891 off < filedata->ngnuchains
14892 && (filedata->gnuchains[off] & 1) == 0;
14893 ++off)
14894 ++length;
14895 lengths[hn] = length;
14896 if (length > maxlength)
14897 maxlength = length;
14898 nsyms += length;
14901 counts = calloc (maxlength + 1, sizeof (*counts));
14902 if (counts == NULL)
14904 free (lengths);
14905 error (_("Out of memory allocating space for gnu histogram counts\n"));
14906 goto err_out;
14909 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
14910 ++counts[lengths[hn]];
14912 if (filedata->ngnubuckets > 0)
14914 uint64_t j;
14915 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
14916 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
14917 for (j = 1; j <= maxlength; ++j)
14919 nzero_counts += counts[j] * j;
14920 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
14921 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
14922 (nzero_counts * 100.0) / nsyms);
14926 free (counts);
14927 free (lengths);
14929 free (filedata->gnubuckets);
14930 filedata->gnubuckets = NULL;
14931 filedata->ngnubuckets = 0;
14932 free (filedata->gnuchains);
14933 filedata->gnuchains = NULL;
14934 filedata->ngnuchains = 0;
14935 free (filedata->mipsxlat);
14936 filedata->mipsxlat = NULL;
14937 return true;
14939 err_out:
14940 free (filedata->gnubuckets);
14941 filedata->gnubuckets = NULL;
14942 filedata->ngnubuckets = 0;
14943 free (filedata->gnuchains);
14944 filedata->gnuchains = NULL;
14945 filedata->ngnuchains = 0;
14946 free (filedata->mipsxlat);
14947 filedata->mipsxlat = NULL;
14948 free (filedata->buckets);
14949 filedata->buckets = NULL;
14950 filedata->nbuckets = 0;
14951 free (filedata->chains);
14952 filedata->chains = NULL;
14953 return false;
14956 static bool
14957 process_syminfo (Filedata * filedata)
14959 unsigned int i;
14961 if (filedata->dynamic_syminfo == NULL
14962 || !do_dynamic)
14963 /* No syminfo, this is ok. */
14964 return true;
14966 /* There better should be a dynamic symbol section. */
14967 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
14968 return false;
14970 if (filedata->is_separate)
14971 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entry:\n",
14972 "\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entries:\n",
14973 filedata->dynamic_syminfo_nent),
14974 filedata->file_name,
14975 filedata->dynamic_syminfo_offset,
14976 filedata->dynamic_syminfo_nent);
14977 else
14978 printf (ngettext ("\nDynamic info segment at offset %#" PRIx64
14979 " contains %d entry:\n",
14980 "\nDynamic info segment at offset %#" PRIx64
14981 " contains %d entries:\n",
14982 filedata->dynamic_syminfo_nent),
14983 filedata->dynamic_syminfo_offset,
14984 filedata->dynamic_syminfo_nent);
14986 printf (_(" Num: Name BoundTo Flags\n"));
14987 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
14989 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
14991 printf ("%4d: ", i);
14992 if (i >= filedata->num_dynamic_syms)
14993 printf (_("<corrupt index>"));
14994 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
14995 print_symbol_name (30, get_dynamic_name (filedata,
14996 filedata->dynamic_symbols[i].st_name));
14997 else
14998 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
14999 putchar (' ');
15001 switch (filedata->dynamic_syminfo[i].si_boundto)
15003 case SYMINFO_BT_SELF:
15004 fputs ("SELF ", stdout);
15005 break;
15006 case SYMINFO_BT_PARENT:
15007 fputs ("PARENT ", stdout);
15008 break;
15009 default:
15010 if (filedata->dynamic_syminfo[i].si_boundto > 0
15011 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
15012 && valid_dynamic_name (filedata,
15013 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
15015 print_symbol_name (10, get_dynamic_name (filedata,
15016 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
15017 putchar (' ' );
15019 else
15020 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
15021 break;
15024 if (flags & SYMINFO_FLG_DIRECT)
15025 printf (" DIRECT");
15026 if (flags & SYMINFO_FLG_PASSTHRU)
15027 printf (" PASSTHRU");
15028 if (flags & SYMINFO_FLG_COPY)
15029 printf (" COPY");
15030 if (flags & SYMINFO_FLG_LAZYLOAD)
15031 printf (" LAZYLOAD");
15033 puts ("");
15036 return true;
15039 /* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
15040 is contained by the region START .. END. The types of ADDR, START
15041 and END should all be the same. Note both ADDR + NELEM and END
15042 point to just beyond the end of the regions that are being tested. */
15043 #define IN_RANGE(START,END,ADDR,NELEM) \
15044 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
15046 /* Check to see if the given reloc needs to be handled in a target specific
15047 manner. If so then process the reloc and return TRUE otherwise return
15048 FALSE.
15050 If called with reloc == NULL, then this is a signal that reloc processing
15051 for the current section has finished, and any saved state should be
15052 discarded. */
15054 static bool
15055 target_specific_reloc_handling (Filedata *filedata,
15056 Elf_Internal_Rela *reloc,
15057 unsigned char *start,
15058 unsigned char *end,
15059 Elf_Internal_Sym *symtab,
15060 uint64_t num_syms)
15062 unsigned int reloc_type = 0;
15063 uint64_t sym_index = 0;
15065 if (reloc)
15067 reloc_type = get_reloc_type (filedata, reloc->r_info);
15068 sym_index = get_reloc_symindex (reloc->r_info);
15071 switch (filedata->file_header.e_machine)
15073 case EM_LOONGARCH:
15075 switch (reloc_type)
15077 /* For .uleb128 .LFE1-.LFB1, loongarch write 0 to object file
15078 at assembly time. */
15079 case 107: /* R_LARCH_ADD_ULEB128. */
15080 case 108: /* R_LARCH_SUB_ULEB128. */
15082 uint64_t value = 0;
15083 unsigned int reloc_size = 0;
15084 int leb_ret = 0;
15086 if (reloc->r_offset < (size_t) (end - start))
15087 value = read_leb128 (start + reloc->r_offset, end, false,
15088 &reloc_size, &leb_ret);
15089 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
15090 error (_("LoongArch ULEB128 field at 0x%lx contains invalid "
15091 "ULEB128 value\n"),
15092 (long) reloc->r_offset);
15094 else if (sym_index >= num_syms)
15095 error (_("%s reloc contains invalid symbol index "
15096 "%" PRIu64 "\n"),
15097 (reloc_type == 107
15098 ? "R_LARCH_ADD_ULEB128"
15099 : "R_LARCH_SUB_ULEB128"),
15100 sym_index);
15101 else
15103 if (reloc_type == 107)
15104 value += reloc->r_addend + symtab[sym_index].st_value;
15105 else
15106 value -= reloc->r_addend + symtab[sym_index].st_value;
15108 /* Write uleb128 value to p. */
15109 bfd_byte *p = start + reloc->r_offset;
15112 bfd_byte c = value & 0x7f;
15113 value >>= 7;
15114 if (--reloc_size != 0)
15115 c |= 0x80;
15116 *p++ = c;
15118 while (reloc_size);
15121 return true;
15124 break;
15127 case EM_MSP430:
15128 case EM_MSP430_OLD:
15130 static Elf_Internal_Sym * saved_sym = NULL;
15132 if (reloc == NULL)
15134 saved_sym = NULL;
15135 return true;
15138 switch (reloc_type)
15140 case 10: /* R_MSP430_SYM_DIFF */
15141 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
15142 if (uses_msp430x_relocs (filedata))
15143 break;
15144 /* Fall through. */
15145 case 21: /* R_MSP430X_SYM_DIFF */
15146 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
15147 /* PR 21139. */
15148 if (sym_index >= num_syms)
15149 error (_("%s reloc contains invalid symbol index "
15150 "%" PRIu64 "\n"), "MSP430 SYM_DIFF", sym_index);
15151 else
15152 saved_sym = symtab + sym_index;
15153 return true;
15155 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
15156 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
15157 goto handle_sym_diff;
15159 case 5: /* R_MSP430_16_BYTE */
15160 case 9: /* R_MSP430_8 */
15161 case 11: /* R_MSP430_GNU_SET_ULEB128 */
15162 if (uses_msp430x_relocs (filedata))
15163 break;
15164 goto handle_sym_diff;
15166 case 2: /* R_MSP430_ABS16 */
15167 case 15: /* R_MSP430X_ABS16 */
15168 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
15169 if (! uses_msp430x_relocs (filedata))
15170 break;
15171 goto handle_sym_diff;
15173 handle_sym_diff:
15174 if (saved_sym != NULL)
15176 uint64_t value;
15177 unsigned int reloc_size = 0;
15178 int leb_ret = 0;
15179 switch (reloc_type)
15181 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
15182 reloc_size = 4;
15183 break;
15184 case 11: /* R_MSP430_GNU_SET_ULEB128 */
15185 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
15186 if (reloc->r_offset < (size_t) (end - start))
15187 read_leb128 (start + reloc->r_offset, end, false,
15188 &reloc_size, &leb_ret);
15189 break;
15190 default:
15191 reloc_size = 2;
15192 break;
15195 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
15196 error (_("MSP430 ULEB128 field at %#" PRIx64
15197 " contains invalid ULEB128 value\n"),
15198 reloc->r_offset);
15199 else if (sym_index >= num_syms)
15200 error (_("%s reloc contains invalid symbol index "
15201 "%" PRIu64 "\n"), "MSP430", sym_index);
15202 else
15204 value = reloc->r_addend + (symtab[sym_index].st_value
15205 - saved_sym->st_value);
15207 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
15208 byte_put (start + reloc->r_offset, value, reloc_size);
15209 else
15210 /* PR 21137 */
15211 error (_("MSP430 sym diff reloc contains invalid offset: "
15212 "%#" PRIx64 "\n"),
15213 reloc->r_offset);
15216 saved_sym = NULL;
15217 return true;
15219 break;
15221 default:
15222 if (saved_sym != NULL)
15223 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
15224 break;
15226 break;
15229 case EM_MN10300:
15230 case EM_CYGNUS_MN10300:
15232 static Elf_Internal_Sym * saved_sym = NULL;
15234 if (reloc == NULL)
15236 saved_sym = NULL;
15237 return true;
15240 switch (reloc_type)
15242 case 34: /* R_MN10300_ALIGN */
15243 return true;
15244 case 33: /* R_MN10300_SYM_DIFF */
15245 if (sym_index >= num_syms)
15246 error (_("%s reloc contains invalid symbol index "
15247 "%" PRIu64 "\n"), "MN10300_SYM_DIFF", sym_index);
15248 else
15249 saved_sym = symtab + sym_index;
15250 return true;
15252 case 1: /* R_MN10300_32 */
15253 case 2: /* R_MN10300_16 */
15254 if (saved_sym != NULL)
15256 int reloc_size = reloc_type == 1 ? 4 : 2;
15257 uint64_t value;
15259 if (sym_index >= num_syms)
15260 error (_("%s reloc contains invalid symbol index "
15261 "%" PRIu64 "\n"), "MN10300", sym_index);
15262 else
15264 value = reloc->r_addend + (symtab[sym_index].st_value
15265 - saved_sym->st_value);
15267 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
15268 byte_put (start + reloc->r_offset, value, reloc_size);
15269 else
15270 error (_("MN10300 sym diff reloc contains invalid offset:"
15271 " %#" PRIx64 "\n"),
15272 reloc->r_offset);
15275 saved_sym = NULL;
15276 return true;
15278 break;
15279 default:
15280 if (saved_sym != NULL)
15281 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
15282 break;
15284 break;
15287 case EM_RL78:
15289 static uint64_t saved_sym1 = 0;
15290 static uint64_t saved_sym2 = 0;
15291 static uint64_t value;
15293 if (reloc == NULL)
15295 saved_sym1 = saved_sym2 = 0;
15296 return true;
15299 switch (reloc_type)
15301 case 0x80: /* R_RL78_SYM. */
15302 saved_sym1 = saved_sym2;
15303 if (sym_index >= num_syms)
15304 error (_("%s reloc contains invalid symbol index "
15305 "%" PRIu64 "\n"), "RL78_SYM", sym_index);
15306 else
15308 saved_sym2 = symtab[sym_index].st_value;
15309 saved_sym2 += reloc->r_addend;
15311 return true;
15313 case 0x83: /* R_RL78_OPsub. */
15314 value = saved_sym1 - saved_sym2;
15315 saved_sym2 = saved_sym1 = 0;
15316 return true;
15317 break;
15319 case 0x41: /* R_RL78_ABS32. */
15320 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
15321 byte_put (start + reloc->r_offset, value, 4);
15322 else
15323 error (_("RL78 sym diff reloc contains invalid offset: "
15324 "%#" PRIx64 "\n"),
15325 reloc->r_offset);
15326 value = 0;
15327 return true;
15329 case 0x43: /* R_RL78_ABS16. */
15330 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
15331 byte_put (start + reloc->r_offset, value, 2);
15332 else
15333 error (_("RL78 sym diff reloc contains invalid offset: "
15334 "%#" PRIx64 "\n"),
15335 reloc->r_offset);
15336 value = 0;
15337 return true;
15339 default:
15340 break;
15342 break;
15346 return false;
15349 /* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
15350 DWARF debug sections. This is a target specific test. Note - we do not
15351 go through the whole including-target-headers-multiple-times route, (as
15352 we have already done with <elf/h8.h>) because this would become very
15353 messy and even then this function would have to contain target specific
15354 information (the names of the relocs instead of their numeric values).
15355 FIXME: This is not the correct way to solve this problem. The proper way
15356 is to have target specific reloc sizing and typing functions created by
15357 the reloc-macros.h header, in the same way that it already creates the
15358 reloc naming functions. */
15360 static bool
15361 is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15363 /* Please keep this table alpha-sorted for ease of visual lookup. */
15364 switch (filedata->file_header.e_machine)
15366 case EM_386:
15367 case EM_IAMCU:
15368 return reloc_type == 1; /* R_386_32. */
15369 case EM_68K:
15370 return reloc_type == 1; /* R_68K_32. */
15371 case EM_860:
15372 return reloc_type == 1; /* R_860_32. */
15373 case EM_960:
15374 return reloc_type == 2; /* R_960_32. */
15375 case EM_AARCH64:
15376 return (reloc_type == 258
15377 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
15378 case EM_BPF:
15379 return reloc_type == 11; /* R_BPF_DATA_32 */
15380 case EM_ADAPTEVA_EPIPHANY:
15381 return reloc_type == 3;
15382 case EM_ALPHA:
15383 return reloc_type == 1; /* R_ALPHA_REFLONG. */
15384 case EM_ARC:
15385 return reloc_type == 1; /* R_ARC_32. */
15386 case EM_ARC_COMPACT:
15387 case EM_ARC_COMPACT2:
15388 case EM_ARC_COMPACT3:
15389 case EM_ARC_COMPACT3_64:
15390 return reloc_type == 4; /* R_ARC_32. */
15391 case EM_ARM:
15392 return reloc_type == 2; /* R_ARM_ABS32 */
15393 case EM_AVR_OLD:
15394 case EM_AVR:
15395 return reloc_type == 1;
15396 case EM_BLACKFIN:
15397 return reloc_type == 0x12; /* R_byte4_data. */
15398 case EM_CRIS:
15399 return reloc_type == 3; /* R_CRIS_32. */
15400 case EM_CR16:
15401 return reloc_type == 3; /* R_CR16_NUM32. */
15402 case EM_CRX:
15403 return reloc_type == 15; /* R_CRX_NUM32. */
15404 case EM_CSKY:
15405 return reloc_type == 1; /* R_CKCORE_ADDR32. */
15406 case EM_CYGNUS_FRV:
15407 return reloc_type == 1;
15408 case EM_CYGNUS_D10V:
15409 case EM_D10V:
15410 return reloc_type == 6; /* R_D10V_32. */
15411 case EM_CYGNUS_D30V:
15412 case EM_D30V:
15413 return reloc_type == 12; /* R_D30V_32_NORMAL. */
15414 case EM_DLX:
15415 return reloc_type == 3; /* R_DLX_RELOC_32. */
15416 case EM_CYGNUS_FR30:
15417 case EM_FR30:
15418 return reloc_type == 3; /* R_FR30_32. */
15419 case EM_FT32:
15420 return reloc_type == 1; /* R_FT32_32. */
15421 case EM_H8S:
15422 case EM_H8_300:
15423 case EM_H8_300H:
15424 return reloc_type == 1; /* R_H8_DIR32. */
15425 case EM_IA_64:
15426 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
15427 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
15428 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
15429 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
15430 case EM_IP2K_OLD:
15431 case EM_IP2K:
15432 return reloc_type == 2; /* R_IP2K_32. */
15433 case EM_IQ2000:
15434 return reloc_type == 2; /* R_IQ2000_32. */
15435 case EM_KVX:
15436 return reloc_type == 2; /* R_KVX_32. */
15437 case EM_LATTICEMICO32:
15438 return reloc_type == 3; /* R_LM32_32. */
15439 case EM_LOONGARCH:
15440 return reloc_type == 1; /* R_LARCH_32. */
15441 case EM_M32C_OLD:
15442 case EM_M32C:
15443 return reloc_type == 3; /* R_M32C_32. */
15444 case EM_M32R:
15445 return reloc_type == 34; /* R_M32R_32_RELA. */
15446 case EM_68HC11:
15447 case EM_68HC12:
15448 return reloc_type == 6; /* R_M68HC11_32. */
15449 case EM_S12Z:
15450 return reloc_type == 7 || /* R_S12Z_EXT32 */
15451 reloc_type == 6; /* R_S12Z_CW32. */
15452 case EM_MCORE:
15453 return reloc_type == 1; /* R_MCORE_ADDR32. */
15454 case EM_CYGNUS_MEP:
15455 return reloc_type == 4; /* R_MEP_32. */
15456 case EM_METAG:
15457 return reloc_type == 2; /* R_METAG_ADDR32. */
15458 case EM_MICROBLAZE:
15459 return reloc_type == 1; /* R_MICROBLAZE_32. */
15460 case EM_MIPS:
15461 return reloc_type == 2; /* R_MIPS_32. */
15462 case EM_MMIX:
15463 return reloc_type == 4; /* R_MMIX_32. */
15464 case EM_CYGNUS_MN10200:
15465 case EM_MN10200:
15466 return reloc_type == 1; /* R_MN10200_32. */
15467 case EM_CYGNUS_MN10300:
15468 case EM_MN10300:
15469 return reloc_type == 1; /* R_MN10300_32. */
15470 case EM_MOXIE:
15471 return reloc_type == 1; /* R_MOXIE_32. */
15472 case EM_MSP430_OLD:
15473 case EM_MSP430:
15474 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
15475 case EM_MT:
15476 return reloc_type == 2; /* R_MT_32. */
15477 case EM_NDS32:
15478 return reloc_type == 20; /* R_NDS32_32_RELA. */
15479 case EM_ALTERA_NIOS2:
15480 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
15481 case EM_NIOS32:
15482 return reloc_type == 1; /* R_NIOS_32. */
15483 case EM_OR1K:
15484 return reloc_type == 1; /* R_OR1K_32. */
15485 case EM_PARISC:
15486 return (reloc_type == 1 /* R_PARISC_DIR32. */
15487 || reloc_type == 2 /* R_PARISC_DIR21L. */
15488 || reloc_type == 41); /* R_PARISC_SECREL32. */
15489 case EM_PJ:
15490 case EM_PJ_OLD:
15491 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
15492 case EM_PPC64:
15493 return reloc_type == 1; /* R_PPC64_ADDR32. */
15494 case EM_PPC:
15495 return reloc_type == 1; /* R_PPC_ADDR32. */
15496 case EM_TI_PRU:
15497 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
15498 case EM_RISCV:
15499 return reloc_type == 1; /* R_RISCV_32. */
15500 case EM_RL78:
15501 return reloc_type == 1; /* R_RL78_DIR32. */
15502 case EM_RX:
15503 return reloc_type == 1; /* R_RX_DIR32. */
15504 case EM_S370:
15505 return reloc_type == 1; /* R_I370_ADDR31. */
15506 case EM_S390_OLD:
15507 case EM_S390:
15508 return reloc_type == 4; /* R_S390_32. */
15509 case EM_SCORE:
15510 return reloc_type == 8; /* R_SCORE_ABS32. */
15511 case EM_SH:
15512 return reloc_type == 1; /* R_SH_DIR32. */
15513 case EM_SPARC32PLUS:
15514 case EM_SPARCV9:
15515 case EM_SPARC:
15516 return reloc_type == 3 /* R_SPARC_32. */
15517 || reloc_type == 23; /* R_SPARC_UA32. */
15518 case EM_SPU:
15519 return reloc_type == 6; /* R_SPU_ADDR32 */
15520 case EM_TI_C6000:
15521 return reloc_type == 1; /* R_C6000_ABS32. */
15522 case EM_TILEGX:
15523 return reloc_type == 2; /* R_TILEGX_32. */
15524 case EM_TILEPRO:
15525 return reloc_type == 1; /* R_TILEPRO_32. */
15526 case EM_CYGNUS_V850:
15527 case EM_V850:
15528 return reloc_type == 6; /* R_V850_ABS32. */
15529 case EM_V800:
15530 return reloc_type == 0x33; /* R_V810_WORD. */
15531 case EM_VAX:
15532 return reloc_type == 1; /* R_VAX_32. */
15533 case EM_VISIUM:
15534 return reloc_type == 3; /* R_VISIUM_32. */
15535 case EM_WEBASSEMBLY:
15536 return reloc_type == 1; /* R_WASM32_32. */
15537 case EM_X86_64:
15538 case EM_L1OM:
15539 case EM_K1OM:
15540 return reloc_type == 10; /* R_X86_64_32. */
15541 case EM_XGATE:
15542 return reloc_type == 4; /* R_XGATE_32. */
15543 case EM_XSTORMY16:
15544 return reloc_type == 1; /* R_XSTROMY16_32. */
15545 case EM_XTENSA_OLD:
15546 case EM_XTENSA:
15547 return reloc_type == 1; /* R_XTENSA_32. */
15548 case EM_Z80:
15549 return reloc_type == 6; /* R_Z80_32. */
15550 default:
15552 static unsigned int prev_warn = 0;
15554 /* Avoid repeating the same warning multiple times. */
15555 if (prev_warn != filedata->file_header.e_machine)
15556 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
15557 filedata->file_header.e_machine);
15558 prev_warn = filedata->file_header.e_machine;
15559 return false;
15564 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15565 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
15567 static bool
15568 is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
15570 switch (filedata->file_header.e_machine)
15571 /* Please keep this table alpha-sorted for ease of visual lookup. */
15573 case EM_386:
15574 case EM_IAMCU:
15575 return reloc_type == 2; /* R_386_PC32. */
15576 case EM_68K:
15577 return reloc_type == 4; /* R_68K_PC32. */
15578 case EM_AARCH64:
15579 return reloc_type == 261; /* R_AARCH64_PREL32 */
15580 case EM_ADAPTEVA_EPIPHANY:
15581 return reloc_type == 6;
15582 case EM_ALPHA:
15583 return reloc_type == 10; /* R_ALPHA_SREL32. */
15584 case EM_ARC_COMPACT:
15585 case EM_ARC_COMPACT2:
15586 case EM_ARC_COMPACT3:
15587 case EM_ARC_COMPACT3_64:
15588 return reloc_type == 49; /* R_ARC_32_PCREL. */
15589 case EM_ARM:
15590 return reloc_type == 3; /* R_ARM_REL32 */
15591 case EM_AVR_OLD:
15592 case EM_AVR:
15593 return reloc_type == 36; /* R_AVR_32_PCREL. */
15594 case EM_LOONGARCH:
15595 return reloc_type == 99; /* R_LARCH_32_PCREL. */
15596 case EM_MICROBLAZE:
15597 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
15598 case EM_OR1K:
15599 return reloc_type == 9; /* R_OR1K_32_PCREL. */
15600 case EM_PARISC:
15601 return reloc_type == 9; /* R_PARISC_PCREL32. */
15602 case EM_PPC:
15603 return reloc_type == 26; /* R_PPC_REL32. */
15604 case EM_PPC64:
15605 return reloc_type == 26; /* R_PPC64_REL32. */
15606 case EM_RISCV:
15607 return reloc_type == 57; /* R_RISCV_32_PCREL. */
15608 case EM_S390_OLD:
15609 case EM_S390:
15610 return reloc_type == 5; /* R_390_PC32. */
15611 case EM_SH:
15612 return reloc_type == 2; /* R_SH_REL32. */
15613 case EM_SPARC32PLUS:
15614 case EM_SPARCV9:
15615 case EM_SPARC:
15616 return reloc_type == 6; /* R_SPARC_DISP32. */
15617 case EM_SPU:
15618 return reloc_type == 13; /* R_SPU_REL32. */
15619 case EM_TILEGX:
15620 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
15621 case EM_TILEPRO:
15622 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
15623 case EM_VISIUM:
15624 return reloc_type == 6; /* R_VISIUM_32_PCREL */
15625 case EM_X86_64:
15626 case EM_L1OM:
15627 case EM_K1OM:
15628 return reloc_type == 2; /* R_X86_64_PC32. */
15629 case EM_VAX:
15630 return reloc_type == 4; /* R_VAX_PCREL32. */
15631 case EM_XTENSA_OLD:
15632 case EM_XTENSA:
15633 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
15634 case EM_KVX:
15635 return reloc_type == 7; /* R_KVX_32_PCREL */
15636 default:
15637 /* Do not abort or issue an error message here. Not all targets use
15638 pc-relative 32-bit relocs in their DWARF debug information and we
15639 have already tested for target coverage in is_32bit_abs_reloc. A
15640 more helpful warning message will be generated by apply_relocations
15641 anyway, so just return. */
15642 return false;
15646 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15647 a 64-bit absolute RELA relocation used in DWARF debug sections. */
15649 static bool
15650 is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15652 switch (filedata->file_header.e_machine)
15654 case EM_AARCH64:
15655 return reloc_type == 257; /* R_AARCH64_ABS64. */
15656 case EM_ARC_COMPACT3_64:
15657 return reloc_type == 5; /* R_ARC_64. */
15658 case EM_ALPHA:
15659 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
15660 case EM_IA_64:
15661 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
15662 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
15663 case EM_LOONGARCH:
15664 return reloc_type == 2; /* R_LARCH_64 */
15665 case EM_PARISC:
15666 return reloc_type == 80; /* R_PARISC_DIR64. */
15667 case EM_PPC64:
15668 return reloc_type == 38; /* R_PPC64_ADDR64. */
15669 case EM_RISCV:
15670 return reloc_type == 2; /* R_RISCV_64. */
15671 case EM_SPARC32PLUS:
15672 case EM_SPARCV9:
15673 case EM_SPARC:
15674 return reloc_type == 32 /* R_SPARC_64. */
15675 || reloc_type == 54; /* R_SPARC_UA64. */
15676 case EM_X86_64:
15677 case EM_L1OM:
15678 case EM_K1OM:
15679 return reloc_type == 1; /* R_X86_64_64. */
15680 case EM_S390_OLD:
15681 case EM_S390:
15682 return reloc_type == 22; /* R_S390_64. */
15683 case EM_TILEGX:
15684 return reloc_type == 1; /* R_TILEGX_64. */
15685 case EM_MIPS:
15686 return reloc_type == 18; /* R_MIPS_64. */
15687 case EM_KVX:
15688 return reloc_type == 3; /* R_KVX_64 */
15689 default:
15690 return false;
15694 /* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
15695 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
15697 static bool
15698 is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
15700 switch (filedata->file_header.e_machine)
15702 case EM_AARCH64:
15703 return reloc_type == 260; /* R_AARCH64_PREL64. */
15704 case EM_ALPHA:
15705 return reloc_type == 11; /* R_ALPHA_SREL64. */
15706 case EM_IA_64:
15707 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
15708 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
15709 case EM_PARISC:
15710 return reloc_type == 72; /* R_PARISC_PCREL64. */
15711 case EM_PPC64:
15712 return reloc_type == 44; /* R_PPC64_REL64. */
15713 case EM_SPARC32PLUS:
15714 case EM_SPARCV9:
15715 case EM_SPARC:
15716 return reloc_type == 46; /* R_SPARC_DISP64. */
15717 case EM_X86_64:
15718 case EM_L1OM:
15719 case EM_K1OM:
15720 return reloc_type == 24; /* R_X86_64_PC64. */
15721 case EM_S390_OLD:
15722 case EM_S390:
15723 return reloc_type == 23; /* R_S390_PC64. */
15724 case EM_TILEGX:
15725 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
15726 default:
15727 return false;
15731 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15732 a 24-bit absolute RELA relocation used in DWARF debug sections. */
15734 static bool
15735 is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15737 switch (filedata->file_header.e_machine)
15739 case EM_CYGNUS_MN10200:
15740 case EM_MN10200:
15741 return reloc_type == 4; /* R_MN10200_24. */
15742 case EM_FT32:
15743 return reloc_type == 5; /* R_FT32_20. */
15744 case EM_Z80:
15745 return reloc_type == 5; /* R_Z80_24. */
15746 default:
15747 return false;
15751 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15752 a 16-bit absolute RELA relocation used in DWARF debug sections. */
15754 static bool
15755 is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15757 /* Please keep this table alpha-sorted for ease of visual lookup. */
15758 switch (filedata->file_header.e_machine)
15760 case EM_ARC:
15761 case EM_ARC_COMPACT:
15762 case EM_ARC_COMPACT2:
15763 case EM_ARC_COMPACT3:
15764 case EM_ARC_COMPACT3_64:
15765 return reloc_type == 2; /* R_ARC_16. */
15766 case EM_ADAPTEVA_EPIPHANY:
15767 return reloc_type == 5;
15768 case EM_AVR_OLD:
15769 case EM_AVR:
15770 return reloc_type == 4; /* R_AVR_16. */
15771 case EM_CYGNUS_D10V:
15772 case EM_D10V:
15773 return reloc_type == 3; /* R_D10V_16. */
15774 case EM_FT32:
15775 return reloc_type == 2; /* R_FT32_16. */
15776 case EM_H8S:
15777 case EM_H8_300:
15778 case EM_H8_300H:
15779 return reloc_type == R_H8_DIR16;
15780 case EM_IP2K_OLD:
15781 case EM_IP2K:
15782 return reloc_type == 1; /* R_IP2K_16. */
15783 case EM_M32C_OLD:
15784 case EM_M32C:
15785 return reloc_type == 1; /* R_M32C_16 */
15786 case EM_CYGNUS_MN10200:
15787 case EM_MN10200:
15788 return reloc_type == 2; /* R_MN10200_16. */
15789 case EM_CYGNUS_MN10300:
15790 case EM_MN10300:
15791 return reloc_type == 2; /* R_MN10300_16. */
15792 case EM_KVX:
15793 return reloc_type == 1; /* R_KVX_16 */
15794 case EM_MSP430:
15795 if (uses_msp430x_relocs (filedata))
15796 return reloc_type == 2; /* R_MSP430_ABS16. */
15797 /* Fall through. */
15798 case EM_MSP430_OLD:
15799 return reloc_type == 5; /* R_MSP430_16_BYTE. */
15800 case EM_NDS32:
15801 return reloc_type == 19; /* R_NDS32_16_RELA. */
15802 case EM_ALTERA_NIOS2:
15803 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
15804 case EM_NIOS32:
15805 return reloc_type == 9; /* R_NIOS_16. */
15806 case EM_OR1K:
15807 return reloc_type == 2; /* R_OR1K_16. */
15808 case EM_RISCV:
15809 return reloc_type == 55; /* R_RISCV_SET16. */
15810 case EM_TI_PRU:
15811 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
15812 case EM_TI_C6000:
15813 return reloc_type == 2; /* R_C6000_ABS16. */
15814 case EM_VISIUM:
15815 return reloc_type == 2; /* R_VISIUM_16. */
15816 case EM_XGATE:
15817 return reloc_type == 3; /* R_XGATE_16. */
15818 case EM_Z80:
15819 return reloc_type == 4; /* R_Z80_16. */
15820 default:
15821 return false;
15825 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15826 a 8-bit absolute RELA relocation used in DWARF debug sections. */
15828 static bool
15829 is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15831 switch (filedata->file_header.e_machine)
15833 case EM_RISCV:
15834 return reloc_type == 54; /* R_RISCV_SET8. */
15835 case EM_Z80:
15836 return reloc_type == 1; /* R_Z80_8. */
15837 case EM_MICROBLAZE:
15838 return (reloc_type == 33 /* R_MICROBLAZE_32_NONE. */
15839 || reloc_type == 0 /* R_MICROBLAZE_NONE. */
15840 || reloc_type == 9 /* R_MICROBLAZE_64_NONE. */);
15841 default:
15842 return false;
15846 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15847 a 6-bit absolute RELA relocation used in DWARF debug sections. */
15849 static bool
15850 is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15852 switch (filedata->file_header.e_machine)
15854 case EM_RISCV:
15855 return reloc_type == 53; /* R_RISCV_SET6. */
15856 default:
15857 return false;
15861 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15862 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
15864 static bool
15865 is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15867 /* Please keep this table alpha-sorted for ease of visual lookup. */
15868 switch (filedata->file_header.e_machine)
15870 case EM_LOONGARCH:
15871 return reloc_type == 50; /* R_LARCH_ADD32. */
15872 case EM_RISCV:
15873 return reloc_type == 35; /* R_RISCV_ADD32. */
15874 default:
15875 return false;
15879 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15880 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
15882 static bool
15883 is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15885 /* Please keep this table alpha-sorted for ease of visual lookup. */
15886 switch (filedata->file_header.e_machine)
15888 case EM_LOONGARCH:
15889 return reloc_type == 55; /* R_LARCH_SUB32. */
15890 case EM_RISCV:
15891 return reloc_type == 39; /* R_RISCV_SUB32. */
15892 default:
15893 return false;
15897 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15898 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
15900 static bool
15901 is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15903 /* Please keep this table alpha-sorted for ease of visual lookup. */
15904 switch (filedata->file_header.e_machine)
15906 case EM_LOONGARCH:
15907 return reloc_type == 51; /* R_LARCH_ADD64. */
15908 case EM_RISCV:
15909 return reloc_type == 36; /* R_RISCV_ADD64. */
15910 default:
15911 return false;
15915 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15916 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
15918 static bool
15919 is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15921 /* Please keep this table alpha-sorted for ease of visual lookup. */
15922 switch (filedata->file_header.e_machine)
15924 case EM_LOONGARCH:
15925 return reloc_type == 56; /* R_LARCH_SUB64. */
15926 case EM_RISCV:
15927 return reloc_type == 40; /* R_RISCV_SUB64. */
15928 default:
15929 return false;
15933 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15934 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
15936 static bool
15937 is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15939 /* Please keep this table alpha-sorted for ease of visual lookup. */
15940 switch (filedata->file_header.e_machine)
15942 case EM_LOONGARCH:
15943 return reloc_type == 48; /* R_LARCH_ADD16. */
15944 case EM_RISCV:
15945 return reloc_type == 34; /* R_RISCV_ADD16. */
15946 default:
15947 return false;
15951 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15952 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
15954 static bool
15955 is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15957 /* Please keep this table alpha-sorted for ease of visual lookup. */
15958 switch (filedata->file_header.e_machine)
15960 case EM_LOONGARCH:
15961 return reloc_type == 53; /* R_LARCH_SUB16. */
15962 case EM_RISCV:
15963 return reloc_type == 38; /* R_RISCV_SUB16. */
15964 default:
15965 return false;
15969 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15970 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
15972 static bool
15973 is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15975 /* Please keep this table alpha-sorted for ease of visual lookup. */
15976 switch (filedata->file_header.e_machine)
15978 case EM_LOONGARCH:
15979 return reloc_type == 47; /* R_LARCH_ADD8. */
15980 case EM_RISCV:
15981 return reloc_type == 33; /* R_RISCV_ADD8. */
15982 default:
15983 return false;
15987 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15988 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
15990 static bool
15991 is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15993 /* Please keep this table alpha-sorted for ease of visual lookup. */
15994 switch (filedata->file_header.e_machine)
15996 case EM_LOONGARCH:
15997 return reloc_type == 52; /* R_LARCH_SUB8. */
15998 case EM_RISCV:
15999 return reloc_type == 37; /* R_RISCV_SUB8. */
16000 default:
16001 return false;
16005 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
16006 a 6-bit inplace add RELA relocation used in DWARF debug sections. */
16008 static bool
16009 is_6bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
16011 switch (filedata->file_header.e_machine)
16013 case EM_LOONGARCH:
16014 return reloc_type == 105; /* R_LARCH_ADD6. */
16015 default:
16016 return false;
16020 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
16021 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
16023 static bool
16024 is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
16026 switch (filedata->file_header.e_machine)
16028 case EM_LOONGARCH:
16029 return reloc_type == 106; /* R_LARCH_SUB6. */
16030 case EM_RISCV:
16031 return reloc_type == 52; /* R_RISCV_SUB6. */
16032 default:
16033 return false;
16037 /* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
16038 relocation entries (possibly formerly used for SHT_GROUP sections). */
16040 static bool
16041 is_none_reloc (Filedata * filedata, unsigned int reloc_type)
16043 switch (filedata->file_header.e_machine)
16045 case EM_386: /* R_386_NONE. */
16046 case EM_68K: /* R_68K_NONE. */
16047 case EM_ADAPTEVA_EPIPHANY:
16048 case EM_ALPHA: /* R_ALPHA_NONE. */
16049 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
16050 case EM_ARC: /* R_ARC_NONE. */
16051 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
16052 case EM_ARC_COMPACT: /* R_ARC_NONE. */
16053 case EM_ARC_COMPACT3: /* R_ARC_NONE. */
16054 case EM_ARC_COMPACT3_64: /* R_ARC_NONE. */
16055 case EM_ARM: /* R_ARM_NONE. */
16056 case EM_CRIS: /* R_CRIS_NONE. */
16057 case EM_FT32: /* R_FT32_NONE. */
16058 case EM_IA_64: /* R_IA64_NONE. */
16059 case EM_K1OM: /* R_X86_64_NONE. */
16060 case EM_KVX: /* R_KVX_NONE. */
16061 case EM_L1OM: /* R_X86_64_NONE. */
16062 case EM_M32R: /* R_M32R_NONE. */
16063 case EM_MIPS: /* R_MIPS_NONE. */
16064 case EM_MN10300: /* R_MN10300_NONE. */
16065 case EM_MOXIE: /* R_MOXIE_NONE. */
16066 case EM_NIOS32: /* R_NIOS_NONE. */
16067 case EM_OR1K: /* R_OR1K_NONE. */
16068 case EM_PARISC: /* R_PARISC_NONE. */
16069 case EM_PPC64: /* R_PPC64_NONE. */
16070 case EM_PPC: /* R_PPC_NONE. */
16071 case EM_RISCV: /* R_RISCV_NONE. */
16072 case EM_S390: /* R_390_NONE. */
16073 case EM_S390_OLD:
16074 case EM_SH: /* R_SH_NONE. */
16075 case EM_SPARC32PLUS:
16076 case EM_SPARC: /* R_SPARC_NONE. */
16077 case EM_SPARCV9:
16078 case EM_TILEGX: /* R_TILEGX_NONE. */
16079 case EM_TILEPRO: /* R_TILEPRO_NONE. */
16080 case EM_TI_C6000:/* R_C6000_NONE. */
16081 case EM_X86_64: /* R_X86_64_NONE. */
16082 case EM_Z80: /* R_Z80_NONE. */
16083 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
16084 return reloc_type == 0;
16086 case EM_AARCH64:
16087 return reloc_type == 0 || reloc_type == 256;
16088 case EM_AVR_OLD:
16089 case EM_AVR:
16090 return (reloc_type == 0 /* R_AVR_NONE. */
16091 || reloc_type == 30 /* R_AVR_DIFF8. */
16092 || reloc_type == 31 /* R_AVR_DIFF16. */
16093 || reloc_type == 32 /* R_AVR_DIFF32. */);
16094 case EM_METAG:
16095 return reloc_type == 3; /* R_METAG_NONE. */
16096 case EM_NDS32:
16097 return (reloc_type == 0 /* R_NDS32_NONE. */
16098 || reloc_type == 205 /* R_NDS32_DIFF8. */
16099 || reloc_type == 206 /* R_NDS32_DIFF16. */
16100 || reloc_type == 207 /* R_NDS32_DIFF32. */
16101 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
16102 case EM_TI_PRU:
16103 return (reloc_type == 0 /* R_PRU_NONE. */
16104 || reloc_type == 65 /* R_PRU_DIFF8. */
16105 || reloc_type == 66 /* R_PRU_DIFF16. */
16106 || reloc_type == 67 /* R_PRU_DIFF32. */);
16107 case EM_XTENSA_OLD:
16108 case EM_XTENSA:
16109 return (reloc_type == 0 /* R_XTENSA_NONE. */
16110 || reloc_type == 17 /* R_XTENSA_DIFF8. */
16111 || reloc_type == 18 /* R_XTENSA_DIFF16. */
16112 || reloc_type == 19 /* R_XTENSA_DIFF32. */
16113 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
16114 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
16115 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
16116 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
16117 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
16118 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
16120 return false;
16123 /* Returns TRUE if there is a relocation against
16124 section NAME at OFFSET bytes. */
16126 bool
16127 reloc_at (struct dwarf_section * dsec, uint64_t offset)
16129 Elf_Internal_Rela * relocs;
16130 Elf_Internal_Rela * rp;
16132 if (dsec == NULL || dsec->reloc_info == NULL)
16133 return false;
16135 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
16137 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
16138 if (rp->r_offset == offset)
16139 return true;
16141 return false;
16144 /* Apply relocations to a section.
16145 Returns TRUE upon success, FALSE otherwise.
16146 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
16147 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
16148 will be set to the number of relocs loaded.
16150 Note: So far support has been added only for those relocations
16151 which can be found in debug sections. FIXME: Add support for
16152 more relocations ? */
16154 static bool
16155 apply_relocations (Filedata *filedata,
16156 const Elf_Internal_Shdr *section,
16157 unsigned char *start,
16158 size_t size,
16159 void **relocs_return,
16160 uint64_t *num_relocs_return)
16162 Elf_Internal_Shdr * relsec;
16163 unsigned char * end = start + size;
16165 if (relocs_return != NULL)
16167 * (Elf_Internal_Rela **) relocs_return = NULL;
16168 * num_relocs_return = 0;
16171 if (filedata->file_header.e_type != ET_REL)
16172 /* No relocs to apply. */
16173 return true;
16175 /* Find the reloc section associated with the section. */
16176 for (relsec = filedata->section_headers;
16177 relsec < filedata->section_headers + filedata->file_header.e_shnum;
16178 ++relsec)
16180 bool is_rela;
16181 uint64_t num_relocs;
16182 Elf_Internal_Rela * relocs;
16183 Elf_Internal_Rela * rp;
16184 Elf_Internal_Shdr * symsec;
16185 Elf_Internal_Sym * symtab;
16186 uint64_t num_syms;
16187 Elf_Internal_Sym * sym;
16189 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
16190 || relsec->sh_info >= filedata->file_header.e_shnum
16191 || filedata->section_headers + relsec->sh_info != section
16192 || relsec->sh_size == 0
16193 || relsec->sh_link >= filedata->file_header.e_shnum)
16194 continue;
16196 symsec = filedata->section_headers + relsec->sh_link;
16197 if (symsec->sh_type != SHT_SYMTAB
16198 && symsec->sh_type != SHT_DYNSYM)
16199 return false;
16201 is_rela = relsec->sh_type == SHT_RELA;
16203 if (is_rela)
16205 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
16206 relsec->sh_size, & relocs, & num_relocs))
16207 return false;
16209 else
16211 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
16212 relsec->sh_size, & relocs, & num_relocs))
16213 return false;
16216 /* SH uses RELA but uses in place value instead of the addend field. */
16217 if (filedata->file_header.e_machine == EM_SH)
16218 is_rela = false;
16220 symtab = get_elf_symbols (filedata, symsec, & num_syms);
16222 for (rp = relocs; rp < relocs + num_relocs; ++rp)
16224 uint64_t addend;
16225 unsigned int reloc_type;
16226 unsigned int reloc_size;
16227 bool reloc_inplace = false;
16228 bool reloc_subtract = false;
16229 unsigned char *rloc;
16230 uint64_t sym_index;
16232 reloc_type = get_reloc_type (filedata, rp->r_info);
16234 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
16235 continue;
16236 else if (is_none_reloc (filedata, reloc_type))
16237 continue;
16238 else if (is_32bit_abs_reloc (filedata, reloc_type)
16239 || is_32bit_pcrel_reloc (filedata, reloc_type))
16240 reloc_size = 4;
16241 else if (is_64bit_abs_reloc (filedata, reloc_type)
16242 || is_64bit_pcrel_reloc (filedata, reloc_type))
16243 reloc_size = 8;
16244 else if (is_24bit_abs_reloc (filedata, reloc_type))
16245 reloc_size = 3;
16246 else if (is_16bit_abs_reloc (filedata, reloc_type))
16247 reloc_size = 2;
16248 else if (is_8bit_abs_reloc (filedata, reloc_type)
16249 || is_6bit_abs_reloc (filedata, reloc_type))
16250 reloc_size = 1;
16251 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
16252 reloc_type))
16253 || is_32bit_inplace_add_reloc (filedata, reloc_type))
16255 reloc_size = 4;
16256 reloc_inplace = true;
16258 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
16259 reloc_type))
16260 || is_64bit_inplace_add_reloc (filedata, reloc_type))
16262 reloc_size = 8;
16263 reloc_inplace = true;
16265 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
16266 reloc_type))
16267 || is_16bit_inplace_add_reloc (filedata, reloc_type))
16269 reloc_size = 2;
16270 reloc_inplace = true;
16272 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
16273 reloc_type))
16274 || is_8bit_inplace_add_reloc (filedata, reloc_type))
16276 reloc_size = 1;
16277 reloc_inplace = true;
16279 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
16280 reloc_type))
16281 || is_6bit_inplace_add_reloc (filedata, reloc_type))
16283 reloc_size = 1;
16284 reloc_inplace = true;
16286 else
16288 static unsigned int prev_reloc = 0;
16290 if (reloc_type != prev_reloc)
16291 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
16292 reloc_type, printable_section_name (filedata, section));
16293 prev_reloc = reloc_type;
16294 continue;
16297 rloc = start + rp->r_offset;
16298 if (!IN_RANGE (start, end, rloc, reloc_size))
16300 warn (_("skipping invalid relocation offset %#" PRIx64
16301 " in section %s\n"),
16302 rp->r_offset,
16303 printable_section_name (filedata, section));
16304 continue;
16307 sym_index = get_reloc_symindex (rp->r_info);
16308 if (sym_index >= num_syms)
16310 warn (_("skipping invalid relocation symbol index %#" PRIx64
16311 " in section %s\n"),
16312 sym_index, printable_section_name (filedata, section));
16313 continue;
16315 sym = symtab + sym_index;
16317 /* If the reloc has a symbol associated with it,
16318 make sure that it is of an appropriate type.
16320 Relocations against symbols without type can happen.
16321 Gcc -feliminate-dwarf2-dups may generate symbols
16322 without type for debug info.
16324 Icc generates relocations against function symbols
16325 instead of local labels.
16327 Relocations against object symbols can happen, eg when
16328 referencing a global array. For an example of this see
16329 the _clz.o binary in libgcc.a. */
16330 if (sym != symtab
16331 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
16332 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
16334 warn (_("skipping unexpected symbol type %s in section %s relocation %tu\n"),
16335 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
16336 printable_section_name (filedata, relsec),
16337 rp - relocs);
16338 continue;
16341 addend = 0;
16342 if (is_rela)
16343 addend += rp->r_addend;
16344 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
16345 partial_inplace. */
16346 if (!is_rela
16347 || (filedata->file_header.e_machine == EM_XTENSA
16348 && reloc_type == 1)
16349 || ((filedata->file_header.e_machine == EM_PJ
16350 || filedata->file_header.e_machine == EM_PJ_OLD)
16351 && reloc_type == 1)
16352 || ((filedata->file_header.e_machine == EM_D30V
16353 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
16354 && reloc_type == 12)
16355 || reloc_inplace)
16357 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
16358 addend += byte_get (rloc, reloc_size) & 0x3f;
16359 else
16360 addend += byte_get (rloc, reloc_size);
16363 if (is_32bit_pcrel_reloc (filedata, reloc_type)
16364 || is_64bit_pcrel_reloc (filedata, reloc_type))
16366 /* On HPPA, all pc-relative relocations are biased by 8. */
16367 if (filedata->file_header.e_machine == EM_PARISC)
16368 addend -= 8;
16369 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
16370 reloc_size);
16372 else if (is_6bit_abs_reloc (filedata, reloc_type)
16373 || is_6bit_inplace_sub_reloc (filedata, reloc_type)
16374 || is_6bit_inplace_add_reloc (filedata, reloc_type))
16376 if (reloc_subtract)
16377 addend -= sym->st_value;
16378 else
16379 addend += sym->st_value;
16380 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
16381 byte_put (rloc, addend, reloc_size);
16383 else if (reloc_subtract)
16384 byte_put (rloc, addend - sym->st_value, reloc_size);
16385 else
16386 byte_put (rloc, addend + sym->st_value, reloc_size);
16389 free (symtab);
16390 /* Let the target specific reloc processing code know that
16391 we have finished with these relocs. */
16392 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
16394 if (relocs_return)
16396 * (Elf_Internal_Rela **) relocs_return = relocs;
16397 * num_relocs_return = num_relocs;
16399 else
16400 free (relocs);
16402 break;
16405 return true;
16408 #ifdef SUPPORT_DISASSEMBLY
16409 static bool
16410 disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
16412 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
16414 /* FIXME: XXX -- to be done --- XXX */
16416 return true;
16418 #endif
16420 /* Reads in the contents of SECTION from FILE, returning a pointer
16421 to a malloc'ed buffer or NULL if something went wrong. */
16423 static char *
16424 get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
16426 uint64_t num_bytes = section->sh_size;
16428 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
16430 printf (_("Section '%s' has no data to dump.\n"),
16431 printable_section_name (filedata, section));
16432 return NULL;
16435 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
16436 _("section contents"));
16439 /* Uncompresses a section that was compressed using zlib/zstd, in place. */
16441 static bool
16442 uncompress_section_contents (bool is_zstd,
16443 unsigned char ** buffer,
16444 uint64_t uncompressed_size,
16445 uint64_t * size,
16446 uint64_t file_size)
16448 uint64_t compressed_size = *size;
16449 unsigned char *compressed_buffer = *buffer;
16450 unsigned char *uncompressed_buffer = NULL;
16451 z_stream strm;
16452 int rc;
16454 /* Similar to bfd_section_size_insane() in the BFD library we expect an
16455 upper limit of ~10x compression. Any compression larger than that is
16456 thought to be due to fuzzing of the compression header. */
16457 if (uncompressed_size > file_size * 10)
16459 error (_("Uncompressed section size is suspiciously large: 0x%" PRIu64 "\n"),
16460 uncompressed_size);
16461 goto fail;
16464 uncompressed_buffer = xmalloc (uncompressed_size);
16466 if (is_zstd)
16468 #ifdef HAVE_ZSTD
16469 size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size,
16470 compressed_buffer, compressed_size);
16471 if (ZSTD_isError (ret))
16472 goto fail;
16473 #endif
16475 else
16477 /* It is possible the section consists of several compressed
16478 buffers concatenated together, so we uncompress in a loop. */
16479 /* PR 18313: The state field in the z_stream structure is supposed
16480 to be invisible to the user (ie us), but some compilers will
16481 still complain about it being used without initialisation. So
16482 we first zero the entire z_stream structure and then set the fields
16483 that we need. */
16484 memset (&strm, 0, sizeof strm);
16485 strm.avail_in = compressed_size;
16486 strm.next_in = (Bytef *)compressed_buffer;
16487 strm.avail_out = uncompressed_size;
16489 rc = inflateInit (&strm);
16490 while (strm.avail_in > 0)
16492 if (rc != Z_OK)
16493 break;
16494 strm.next_out = ((Bytef *)uncompressed_buffer
16495 + (uncompressed_size - strm.avail_out));
16496 rc = inflate (&strm, Z_FINISH);
16497 if (rc != Z_STREAM_END)
16498 break;
16499 rc = inflateReset (&strm);
16501 if (inflateEnd (&strm) != Z_OK || rc != Z_OK || strm.avail_out != 0)
16502 goto fail;
16505 *buffer = uncompressed_buffer;
16506 *size = uncompressed_size;
16507 return true;
16509 fail:
16510 free (uncompressed_buffer);
16511 /* Indicate decompression failure. */
16512 *buffer = NULL;
16513 return false;
16516 static uint64_t
16517 maybe_expand_or_relocate_section (Elf_Internal_Shdr * section,
16518 Filedata * filedata,
16519 unsigned char ** start_ptr,
16520 bool relocate)
16522 uint64_t section_size = section->sh_size;
16523 unsigned char * start = * start_ptr;
16525 if (decompress_dumps)
16527 uint64_t new_size = section_size;
16528 uint64_t uncompressed_size = 0;
16529 bool is_zstd = false;
16531 if ((section->sh_flags & SHF_COMPRESSED) != 0)
16533 Elf_Internal_Chdr chdr;
16534 unsigned int compression_header_size
16535 = get_compression_header (& chdr, start, section_size);
16537 if (compression_header_size == 0)
16538 /* An error message will have already been generated
16539 by get_compression_header. */
16540 return (uint64_t) -1;
16542 if (chdr.ch_type == ch_compress_zlib)
16544 #ifdef HAVE_ZSTD
16545 else if (chdr.ch_type == ch_compress_zstd)
16546 is_zstd = true;
16547 #endif
16548 else
16550 warn (_("section '%s' has unsupported compress type: %d\n"),
16551 printable_section_name (filedata, section), chdr.ch_type);
16552 return (uint64_t) -1;
16555 uncompressed_size = chdr.ch_size;
16556 start += compression_header_size;
16557 new_size -= compression_header_size;
16559 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
16561 /* Read the zlib header. In this case, it should be "ZLIB"
16562 followed by the uncompressed section size, 8 bytes in
16563 big-endian order. */
16564 uncompressed_size = start[4]; uncompressed_size <<= 8;
16565 uncompressed_size += start[5]; uncompressed_size <<= 8;
16566 uncompressed_size += start[6]; uncompressed_size <<= 8;
16567 uncompressed_size += start[7]; uncompressed_size <<= 8;
16568 uncompressed_size += start[8]; uncompressed_size <<= 8;
16569 uncompressed_size += start[9]; uncompressed_size <<= 8;
16570 uncompressed_size += start[10]; uncompressed_size <<= 8;
16571 uncompressed_size += start[11];
16572 start += 12;
16573 new_size -= 12;
16576 if (uncompressed_size)
16578 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
16579 &new_size, filedata->file_size))
16580 section_size = new_size;
16581 else
16583 error (_("Unable to decompress section %s\n"),
16584 printable_section_name (filedata, section));
16585 return (uint64_t) -1;
16588 else
16589 start = * start_ptr;
16591 else if (((section->sh_flags & SHF_COMPRESSED) != 0)
16592 || (section_size > 12 && streq ((char *) start, "ZLIB")))
16594 printf (_(" NOTE: This section is compressed, but its contents have NOT been expanded for this dump.\n"));
16597 if (relocate)
16599 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
16600 return (uint64_t) -1;
16602 else
16604 Elf_Internal_Shdr *relsec;
16606 /* If the section being dumped has relocations against it the user might
16607 be expecting these relocations to have been applied. Check for this
16608 case and issue a warning message in order to avoid confusion.
16609 FIXME: Maybe we ought to have an option that dumps a section with
16610 relocs applied ? */
16611 for (relsec = filedata->section_headers;
16612 relsec < filedata->section_headers + filedata->file_header.e_shnum;
16613 ++relsec)
16615 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
16616 || relsec->sh_info >= filedata->file_header.e_shnum
16617 || filedata->section_headers + relsec->sh_info != section
16618 || relsec->sh_size == 0
16619 || relsec->sh_link >= filedata->file_header.e_shnum)
16620 continue;
16622 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
16623 break;
16627 * start_ptr = start;
16628 return section_size;
16631 static bool
16632 dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
16634 uint64_t num_bytes;
16635 unsigned char *data;
16636 unsigned char *end;
16637 unsigned char *real_start;
16638 unsigned char *start;
16639 bool some_strings_shown;
16641 real_start = start = (unsigned char *) get_section_contents (section, filedata);
16642 if (start == NULL)
16643 /* PR 21820: Do not fail if the section was empty. */
16644 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
16646 num_bytes = section->sh_size;
16648 if (filedata->is_separate)
16649 printf (_("\nString dump of section '%s' in linked file %s:\n"),
16650 printable_section_name (filedata, section),
16651 filedata->file_name);
16652 else
16653 printf (_("\nString dump of section '%s':\n"),
16654 printable_section_name (filedata, section));
16656 num_bytes = maybe_expand_or_relocate_section (section, filedata, & start, false);
16657 if (num_bytes == (uint64_t) -1)
16658 goto error_out;
16660 data = start;
16661 end = start + num_bytes;
16662 some_strings_shown = false;
16664 #ifdef HAVE_MBSTATE_T
16665 mbstate_t state;
16666 /* Initialise the multibyte conversion state. */
16667 memset (& state, 0, sizeof (state));
16668 #endif
16670 bool continuing = false;
16672 while (data < end)
16674 while (!ISPRINT (* data))
16675 if (++ data >= end)
16676 break;
16678 if (data < end)
16680 size_t maxlen = end - data;
16682 if (continuing)
16684 printf (" ");
16685 continuing = false;
16687 else
16689 printf (" [%6tx] ", data - start);
16692 if (maxlen > 0)
16694 char c = 0;
16696 while (maxlen)
16698 c = *data++;
16700 if (c == 0)
16701 break;
16703 /* PR 25543: Treat new-lines as string-ending characters. */
16704 if (c == '\n')
16706 printf ("\\n\n");
16707 if (*data != 0)
16708 continuing = true;
16709 break;
16712 /* Do not print control characters directly as they can affect terminal
16713 settings. Such characters usually appear in the names generated
16714 by the assembler for local labels. */
16715 if (ISCNTRL (c))
16717 printf ("^%c", c + 0x40);
16719 else if (ISPRINT (c))
16721 putchar (c);
16723 else
16725 size_t n;
16726 #ifdef HAVE_MBSTATE_T
16727 wchar_t w;
16728 #endif
16729 /* Let printf do the hard work of displaying multibyte characters. */
16730 printf ("%.1s", data - 1);
16731 #ifdef HAVE_MBSTATE_T
16732 /* Try to find out how many bytes made up the character that was
16733 just printed. Advance the symbol pointer past the bytes that
16734 were displayed. */
16735 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
16736 #else
16737 n = 1;
16738 #endif
16739 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
16740 data += (n - 1);
16744 if (c != '\n')
16745 putchar ('\n');
16747 else
16749 printf (_("<corrupt>\n"));
16750 data = end;
16752 some_strings_shown = true;
16756 if (! some_strings_shown)
16757 printf (_(" No strings found in this section."));
16759 free (real_start);
16761 putchar ('\n');
16762 return true;
16764 error_out:
16765 free (real_start);
16766 return false;
16769 static bool
16770 dump_section_as_bytes (Elf_Internal_Shdr *section,
16771 Filedata *filedata,
16772 bool relocate)
16774 size_t bytes;
16775 uint64_t section_size;
16776 uint64_t addr;
16777 unsigned char *data;
16778 unsigned char *real_start;
16779 unsigned char *start;
16781 real_start = start = (unsigned char *) get_section_contents (section, filedata);
16782 if (start == NULL)
16783 /* PR 21820: Do not fail if the section was empty. */
16784 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
16786 section_size = section->sh_size;
16788 if (filedata->is_separate)
16789 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
16790 printable_section_name (filedata, section),
16791 filedata->file_name);
16792 else
16793 printf (_("\nHex dump of section '%s':\n"),
16794 printable_section_name (filedata, section));
16796 section_size = maybe_expand_or_relocate_section (section, filedata, & start, relocate);
16797 if (section_size == (uint64_t) -1)
16798 goto error_out;
16800 addr = section->sh_addr;
16801 bytes = section_size;
16802 data = start;
16804 while (bytes)
16806 int j;
16807 int k;
16808 int lbytes;
16810 lbytes = (bytes > 16 ? 16 : bytes);
16812 printf (" 0x%8.8" PRIx64 " ", addr);
16814 for (j = 0; j < 16; j++)
16816 if (j < lbytes)
16817 printf ("%2.2x", data[j]);
16818 else
16819 printf (" ");
16821 if ((j & 3) == 3)
16822 printf (" ");
16825 for (j = 0; j < lbytes; j++)
16827 k = data[j];
16828 if (k >= ' ' && k < 0x7f)
16829 printf ("%c", k);
16830 else
16831 printf (".");
16834 putchar ('\n');
16836 data += lbytes;
16837 addr += lbytes;
16838 bytes -= lbytes;
16841 free (real_start);
16843 putchar ('\n');
16844 return true;
16846 error_out:
16847 free (real_start);
16848 return false;
16851 #ifdef ENABLE_LIBCTF
16852 static ctf_sect_t *
16853 shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
16855 buf->cts_name = printable_section_name (filedata, shdr);
16856 buf->cts_size = shdr->sh_size;
16857 buf->cts_entsize = shdr->sh_entsize;
16859 return buf;
16862 /* Formatting callback function passed to ctf_dump. Returns either the pointer
16863 it is passed, or a pointer to newly-allocated storage, in which case
16864 dump_ctf() will free it when it no longer needs it. */
16866 static char *
16867 dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
16868 char *s, void *arg)
16870 const char *blanks = arg;
16871 return xasprintf ("%s%s", blanks, s);
16874 /* Dump CTF errors/warnings. */
16875 static void
16876 dump_ctf_errs (ctf_dict_t *fp)
16878 ctf_next_t *it = NULL;
16879 char *errtext;
16880 int is_warning;
16881 int err;
16883 /* Dump accumulated errors and warnings. */
16884 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
16886 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
16887 errtext);
16888 free (errtext);
16890 if (err != ECTF_NEXT_END)
16891 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
16894 /* Dump one CTF archive member. */
16896 static void
16897 dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
16898 size_t member)
16900 const char *things[] = {"Header", "Labels", "Data objects",
16901 "Function objects", "Variables", "Types", "Strings",
16902 ""};
16903 const char **thing;
16904 size_t i;
16906 /* Don't print out the name of the default-named archive member if it appears
16907 first in the list. The name .ctf appears everywhere, even for things that
16908 aren't really archives, so printing it out is liable to be confusing; also,
16909 the common case by far is for only one archive member to exist, and hiding
16910 it in that case seems worthwhile. */
16912 if (strcmp (name, ".ctf") != 0 || member != 0)
16913 printf (_("\nCTF archive member: %s:\n"), name);
16915 if (ctf_parent_name (ctf) != NULL)
16916 ctf_import (ctf, parent);
16918 for (i = 0, thing = things; *thing[0]; thing++, i++)
16920 ctf_dump_state_t *s = NULL;
16921 char *item;
16923 printf ("\n %s:\n", *thing);
16924 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
16925 (void *) " ")) != NULL)
16927 printf ("%s\n", item);
16928 free (item);
16931 if (ctf_errno (ctf))
16933 error (_("Iteration failed: %s, %s\n"), *thing,
16934 ctf_errmsg (ctf_errno (ctf)));
16935 break;
16939 dump_ctf_errs (ctf);
16942 static bool
16943 dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
16945 Elf_Internal_Shdr * symtab_sec = NULL;
16946 Elf_Internal_Shdr * strtab_sec = NULL;
16947 void * data = NULL;
16948 void * symdata = NULL;
16949 void * strdata = NULL;
16950 ctf_sect_t ctfsect, symsect, strsect;
16951 ctf_sect_t * symsectp = NULL;
16952 ctf_sect_t * strsectp = NULL;
16953 ctf_archive_t * ctfa = NULL;
16954 ctf_dict_t * parent = NULL;
16955 ctf_dict_t * fp;
16957 ctf_next_t *i = NULL;
16958 const char *name;
16959 size_t member = 0;
16960 int err;
16961 bool ret = false;
16963 shdr_to_ctf_sect (&ctfsect, section, filedata);
16964 data = get_section_contents (section, filedata);
16965 ctfsect.cts_data = data;
16967 if (!dump_ctf_symtab_name)
16968 dump_ctf_symtab_name = strdup (".dynsym");
16970 if (!dump_ctf_strtab_name)
16971 dump_ctf_strtab_name = strdup (".dynstr");
16973 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
16975 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
16977 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
16978 goto fail;
16980 if ((symdata = (void *) get_data (NULL, filedata,
16981 symtab_sec->sh_offset, 1,
16982 symtab_sec->sh_size,
16983 _("symbols"))) == NULL)
16984 goto fail;
16985 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
16986 symsect.cts_data = symdata;
16989 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
16991 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
16993 error (_("No string table section named %s\n"),
16994 dump_ctf_strtab_name);
16995 goto fail;
16997 if ((strdata = (void *) get_data (NULL, filedata,
16998 strtab_sec->sh_offset, 1,
16999 strtab_sec->sh_size,
17000 _("strings"))) == NULL)
17001 goto fail;
17002 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
17003 strsect.cts_data = strdata;
17006 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
17007 libctf papers over the difference, so we can pretend it is always an
17008 archive. */
17010 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
17012 dump_ctf_errs (NULL);
17013 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
17014 goto fail;
17017 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
17018 != ELFDATA2MSB);
17020 /* Preload the parent dict, since it will need to be imported into every
17021 child in turn. */
17022 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
17024 dump_ctf_errs (NULL);
17025 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
17026 goto fail;
17029 ret = true;
17031 if (filedata->is_separate)
17032 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
17033 printable_section_name (filedata, section),
17034 filedata->file_name);
17035 else
17036 printf (_("\nDump of CTF section '%s':\n"),
17037 printable_section_name (filedata, section));
17039 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
17040 dump_ctf_archive_member (fp, name, parent, member++);
17041 if (err != ECTF_NEXT_END)
17043 dump_ctf_errs (NULL);
17044 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
17045 ret = false;
17048 fail:
17049 ctf_dict_close (parent);
17050 ctf_close (ctfa);
17051 free (data);
17052 free (symdata);
17053 free (strdata);
17054 return ret;
17056 #endif
17058 static bool
17059 dump_section_as_sframe (Elf_Internal_Shdr * section, Filedata * filedata)
17061 void * data = NULL;
17062 sframe_decoder_ctx *sfd_ctx = NULL;
17063 const char *print_name = printable_section_name (filedata, section);
17065 bool ret = true;
17066 size_t sf_size;
17067 int err = 0;
17069 if (strcmp (print_name, "") == 0)
17071 error (_("Section name must be provided \n"));
17072 ret = false;
17073 return ret;
17076 data = get_section_contents (section, filedata);
17077 sf_size = section->sh_size;
17078 /* Decode the contents of the section. */
17079 sfd_ctx = sframe_decode ((const char*)data, sf_size, &err);
17080 if (!sfd_ctx)
17082 ret = false;
17083 error (_("SFrame decode failure: %s\n"), sframe_errmsg (err));
17084 goto fail;
17087 printf (_("Contents of the SFrame section %s:"), print_name);
17088 /* Dump the contents as text. */
17089 dump_sframe (sfd_ctx, section->sh_addr);
17091 fail:
17092 free (data);
17093 return ret;
17096 static bool
17097 load_specific_debug_section (enum dwarf_section_display_enum debug,
17098 const Elf_Internal_Shdr * sec,
17099 void * data)
17101 struct dwarf_section * section = &debug_displays [debug].section;
17102 char buf [64];
17103 Filedata * filedata = (Filedata *) data;
17105 if (section->start != NULL)
17107 /* If it is already loaded, do nothing. */
17108 if (streq (section->filename, filedata->file_name))
17109 return true;
17110 free (section->start);
17113 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
17114 section->address = sec->sh_addr;
17115 section->filename = filedata->file_name;
17116 section->start = (unsigned char *) get_data (NULL, filedata,
17117 sec->sh_offset, 1,
17118 sec->sh_size, buf);
17119 if (section->start == NULL)
17120 section->size = 0;
17121 else
17123 unsigned char *start = section->start;
17124 uint64_t size = sec->sh_size;
17125 uint64_t uncompressed_size = 0;
17126 bool is_zstd = false;
17128 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
17130 Elf_Internal_Chdr chdr;
17131 unsigned int compression_header_size;
17133 if (size < (is_32bit_elf
17134 ? sizeof (Elf32_External_Chdr)
17135 : sizeof (Elf64_External_Chdr)))
17137 warn (_("compressed section %s is too small to contain a compression header\n"),
17138 section->name);
17139 return false;
17142 compression_header_size = get_compression_header (&chdr, start, size);
17143 if (compression_header_size == 0)
17144 /* An error message will have already been generated
17145 by get_compression_header. */
17146 return false;
17148 if (chdr.ch_type == ch_compress_zlib)
17150 #ifdef HAVE_ZSTD
17151 else if (chdr.ch_type == ch_compress_zstd)
17152 is_zstd = true;
17153 #endif
17154 else
17156 warn (_("section '%s' has unsupported compress type: %d\n"),
17157 section->name, chdr.ch_type);
17158 return false;
17160 uncompressed_size = chdr.ch_size;
17161 start += compression_header_size;
17162 size -= compression_header_size;
17164 else if (size > 12 && streq ((char *) start, "ZLIB"))
17166 /* Read the zlib header. In this case, it should be "ZLIB"
17167 followed by the uncompressed section size, 8 bytes in
17168 big-endian order. */
17169 uncompressed_size = start[4]; uncompressed_size <<= 8;
17170 uncompressed_size += start[5]; uncompressed_size <<= 8;
17171 uncompressed_size += start[6]; uncompressed_size <<= 8;
17172 uncompressed_size += start[7]; uncompressed_size <<= 8;
17173 uncompressed_size += start[8]; uncompressed_size <<= 8;
17174 uncompressed_size += start[9]; uncompressed_size <<= 8;
17175 uncompressed_size += start[10]; uncompressed_size <<= 8;
17176 uncompressed_size += start[11];
17177 start += 12;
17178 size -= 12;
17181 if (uncompressed_size)
17183 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
17184 &size, filedata->file_size))
17186 /* Free the compressed buffer, update the section buffer
17187 and the section size if uncompress is successful. */
17188 free (section->start);
17189 section->start = start;
17191 else
17193 error (_("Unable to decompress section %s\n"),
17194 printable_section_name (filedata, sec));
17195 return false;
17199 section->size = size;
17202 if (section->start == NULL)
17203 return false;
17205 if (debug_displays [debug].relocate)
17207 if (! apply_relocations (filedata, sec, section->start, section->size,
17208 & section->reloc_info, & section->num_relocs))
17209 return false;
17211 else
17213 section->reloc_info = NULL;
17214 section->num_relocs = 0;
17217 return true;
17220 #if HAVE_LIBDEBUGINFOD
17221 /* Return a hex string representation of the build-id. */
17222 unsigned char *
17223 get_build_id (void * data)
17225 Filedata * filedata = (Filedata *) data;
17226 Elf_Internal_Shdr * shdr;
17227 size_t i;
17229 /* Iterate through notes to find note.gnu.build-id.
17230 FIXME: Only the first note in any note section is examined. */
17231 for (i = 0, shdr = filedata->section_headers;
17232 i < filedata->file_header.e_shnum && shdr != NULL;
17233 i++, shdr++)
17235 if (shdr->sh_type != SHT_NOTE)
17236 continue;
17238 char * next;
17239 char * end;
17240 size_t data_remaining;
17241 size_t min_notesz;
17242 Elf_External_Note * enote;
17243 Elf_Internal_Note inote;
17245 uint64_t offset = shdr->sh_offset;
17246 uint64_t align = shdr->sh_addralign;
17247 uint64_t length = shdr->sh_size;
17249 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
17250 if (enote == NULL)
17251 continue;
17253 if (align < 4)
17254 align = 4;
17255 else if (align != 4 && align != 8)
17257 free (enote);
17258 continue;
17261 end = (char *) enote + length;
17262 data_remaining = end - (char *) enote;
17264 if (!is_ia64_vms (filedata))
17266 min_notesz = offsetof (Elf_External_Note, name);
17267 if (data_remaining < min_notesz)
17269 warn (_("\
17270 malformed note encountered in section %s whilst scanning for build-id note\n"),
17271 printable_section_name (filedata, shdr));
17272 free (enote);
17273 continue;
17275 data_remaining -= min_notesz;
17277 inote.type = BYTE_GET (enote->type);
17278 inote.namesz = BYTE_GET (enote->namesz);
17279 inote.namedata = enote->name;
17280 inote.descsz = BYTE_GET (enote->descsz);
17281 inote.descdata = ((char *) enote
17282 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
17283 inote.descpos = offset + (inote.descdata - (char *) enote);
17284 next = ((char *) enote
17285 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
17287 else
17289 Elf64_External_VMS_Note *vms_enote;
17291 /* PR binutils/15191
17292 Make sure that there is enough data to read. */
17293 min_notesz = offsetof (Elf64_External_VMS_Note, name);
17294 if (data_remaining < min_notesz)
17296 warn (_("\
17297 malformed note encountered in section %s whilst scanning for build-id note\n"),
17298 printable_section_name (filedata, shdr));
17299 free (enote);
17300 continue;
17302 data_remaining -= min_notesz;
17304 vms_enote = (Elf64_External_VMS_Note *) enote;
17305 inote.type = BYTE_GET (vms_enote->type);
17306 inote.namesz = BYTE_GET (vms_enote->namesz);
17307 inote.namedata = vms_enote->name;
17308 inote.descsz = BYTE_GET (vms_enote->descsz);
17309 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
17310 inote.descpos = offset + (inote.descdata - (char *) enote);
17311 next = inote.descdata + align_power (inote.descsz, 3);
17314 /* Skip malformed notes. */
17315 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
17316 || (size_t) (inote.descdata - inote.namedata) > data_remaining
17317 || (size_t) (next - inote.descdata) < inote.descsz
17318 || ((size_t) (next - inote.descdata)
17319 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
17321 warn (_("\
17322 malformed note encountered in section %s whilst scanning for build-id note\n"),
17323 printable_section_name (filedata, shdr));
17324 free (enote);
17325 continue;
17328 /* Check if this is the build-id note. If so then convert the build-id
17329 bytes to a hex string. */
17330 if (inote.namesz > 0
17331 && startswith (inote.namedata, "GNU")
17332 && inote.type == NT_GNU_BUILD_ID)
17334 size_t j;
17335 char * build_id;
17337 build_id = malloc (inote.descsz * 2 + 1);
17338 if (build_id == NULL)
17340 free (enote);
17341 return NULL;
17344 for (j = 0; j < inote.descsz; ++j)
17345 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
17346 build_id[inote.descsz * 2] = '\0';
17347 free (enote);
17349 return (unsigned char *) build_id;
17351 free (enote);
17354 return NULL;
17356 #endif /* HAVE_LIBDEBUGINFOD */
17358 /* If this is not NULL, load_debug_section will only look for sections
17359 within the list of sections given here. */
17360 static unsigned int * section_subset = NULL;
17362 bool
17363 load_debug_section (enum dwarf_section_display_enum debug, void * data)
17365 struct dwarf_section * section = &debug_displays [debug].section;
17366 Elf_Internal_Shdr * sec;
17367 Filedata * filedata = (Filedata *) data;
17369 if (!dump_any_debugging)
17370 return false;
17372 /* Without section headers we cannot find any sections. */
17373 if (filedata->section_headers == NULL)
17374 return false;
17376 if (filedata->string_table == NULL
17377 && filedata->file_header.e_shstrndx != SHN_UNDEF
17378 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
17380 Elf_Internal_Shdr * strs;
17382 /* Read in the string table, so that we have section names to scan. */
17383 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
17385 if (strs != NULL && strs->sh_size != 0)
17387 filedata->string_table
17388 = (char *) get_data (NULL, filedata, strs->sh_offset,
17389 1, strs->sh_size, _("string table"));
17391 filedata->string_table_length
17392 = filedata->string_table != NULL ? strs->sh_size : 0;
17396 /* Locate the debug section. */
17397 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
17398 if (sec != NULL)
17399 section->name = section->uncompressed_name;
17400 else
17402 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
17403 if (sec != NULL)
17404 section->name = section->compressed_name;
17406 if (sec == NULL)
17407 return false;
17409 /* If we're loading from a subset of sections, and we've loaded
17410 a section matching this name before, it's likely that it's a
17411 different one. */
17412 if (section_subset != NULL)
17413 free_debug_section (debug);
17415 return load_specific_debug_section (debug, sec, data);
17418 void
17419 free_debug_section (enum dwarf_section_display_enum debug)
17421 struct dwarf_section * section = &debug_displays [debug].section;
17423 if (section->start == NULL)
17424 return;
17426 free ((char *) section->start);
17427 section->start = NULL;
17428 section->address = 0;
17429 section->size = 0;
17431 free (section->reloc_info);
17432 section->reloc_info = NULL;
17433 section->num_relocs = 0;
17436 static bool
17437 display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
17439 const char *name = (section_name_valid (filedata, section)
17440 ? section_name (filedata, section) : "");
17441 const char *print_name = printable_section_name (filedata, section);
17442 uint64_t length;
17443 bool result = true;
17444 int i;
17446 length = section->sh_size;
17447 if (length == 0)
17449 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
17450 return true;
17452 if (section->sh_type == SHT_NOBITS)
17454 /* There is no point in dumping the contents of a debugging section
17455 which has the NOBITS type - the bits in the file will be random.
17456 This can happen when a file containing a .eh_frame section is
17457 stripped with the --only-keep-debug command line option. */
17458 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
17459 print_name);
17460 return false;
17463 if (startswith (name, ".gnu.linkonce.wi."))
17464 name = ".debug_info";
17466 /* See if we know how to display the contents of this section. */
17467 for (i = 0; i < max; i++)
17469 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
17470 struct dwarf_section_display * display = debug_displays + i;
17471 struct dwarf_section * sec = & display->section;
17473 if (streq (sec->uncompressed_name, name)
17474 || (id == line && startswith (name, ".debug_line."))
17475 || streq (sec->compressed_name, name))
17477 bool secondary = (section != find_section (filedata, name));
17479 if (secondary)
17480 free_debug_section (id);
17482 if (i == line && startswith (name, ".debug_line."))
17483 sec->name = name;
17484 else if (streq (sec->uncompressed_name, name))
17485 sec->name = sec->uncompressed_name;
17486 else
17487 sec->name = sec->compressed_name;
17489 if (load_specific_debug_section (id, section, filedata))
17491 /* If this debug section is part of a CU/TU set in a .dwp file,
17492 restrict load_debug_section to the sections in that set. */
17493 section_subset = find_cu_tu_set (filedata, shndx);
17495 result &= display->display (sec, filedata);
17497 section_subset = NULL;
17499 if (secondary || (id != info && id != abbrev && id != debug_addr))
17500 free_debug_section (id);
17502 break;
17506 if (i == max)
17508 printf (_("Unrecognized debug section: %s\n"), print_name);
17509 result = false;
17512 return result;
17515 /* Set DUMP_SECTS for all sections where dumps were requested
17516 based on section name. */
17518 static void
17519 initialise_dumps_byname (Filedata * filedata)
17521 struct dump_list_entry * cur;
17523 for (cur = dump_sects_byname; cur; cur = cur->next)
17525 unsigned int i;
17526 bool any = false;
17528 for (i = 0; i < filedata->file_header.e_shnum; i++)
17529 if (section_name_valid (filedata, filedata->section_headers + i)
17530 && streq (section_name (filedata, filedata->section_headers + i),
17531 cur->name))
17533 request_dump_bynumber (&filedata->dump, i, cur->type);
17534 any = true;
17537 if (!any && !filedata->is_separate)
17538 warn (_("Section '%s' was not dumped because it does not exist\n"),
17539 cur->name);
17543 static bool
17544 process_section_contents (Filedata * filedata)
17546 Elf_Internal_Shdr * section;
17547 unsigned int i;
17548 bool res = true;
17550 if (! do_dump)
17551 return true;
17553 initialise_dumps_byname (filedata);
17555 for (i = 0, section = filedata->section_headers;
17556 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
17557 i++, section++)
17559 dump_type dump = filedata->dump.dump_sects[i];
17561 if (filedata->is_separate && ! process_links)
17562 dump &= DEBUG_DUMP;
17564 if (dump & AUTO_DUMP)
17566 switch (section->sh_type)
17568 case SHT_PROGBITS:
17569 /* FIXME: There are lots of different type of section that have
17570 SHT_PROGBITS set in their header - code, debug info, etc. So
17571 we should check the section's name and interpret its contents
17572 that way, rather than just defaulting to a byte dump. */
17573 #ifdef SUPPORT_DISASSEMBLY
17574 res &= disassemble_section (section, filedata);
17575 #else
17576 res &= dump_section_as_bytes (section, filedata, false);
17577 #endif
17578 break;
17580 case SHT_DYNSYM:
17581 case SHT_SYMTAB:
17582 res &= dump_symbol_section (section, filedata);
17583 break;
17585 case SHT_STRTAB:
17586 res &= dump_section_as_strings (section, filedata);
17587 break;
17589 case SHT_RELA:
17590 case SHT_REL:
17591 case SHT_RELR:
17592 res &= display_relocations (section, filedata);
17593 break;
17595 case SHT_NOTE:
17596 res &= process_notes_at (filedata, section, section->sh_offset,
17597 section->sh_size, section->sh_addralign);
17598 break;
17600 case SHT_NULL:
17601 inform (_("Unable to display section %d - it has a NULL type\n"), i);
17602 break;
17604 case SHT_NOBITS:
17605 inform (_("Unable to display section %d - it has no contents\n"), i);
17606 break;
17608 case SHT_HASH:
17609 case SHT_DYNAMIC:
17610 case SHT_GROUP:
17611 case SHT_GNU_ATTRIBUTES:
17612 /* FIXME: Implement these. */
17613 /* Fall through. */
17614 default:
17615 /* FIXME: Add Proc and OS specific section types ? */
17616 warn (_("Unable to determine how to dump section %d (type %#x)\n"),
17617 i, section->sh_type);
17618 res = false;
17619 break;
17623 #ifdef SUPPORT_DISASSEMBLY
17624 if (dump & DISASS_DUMP)
17626 if (! disassemble_section (section, filedata))
17627 res = false;
17629 #endif
17630 if (dump & HEX_DUMP)
17632 if (! dump_section_as_bytes (section, filedata, false))
17633 res = false;
17636 if (dump & RELOC_DUMP)
17638 if (! dump_section_as_bytes (section, filedata, true))
17639 res = false;
17642 if (dump & STRING_DUMP)
17644 if (! dump_section_as_strings (section, filedata))
17645 res = false;
17648 if (dump & DEBUG_DUMP)
17650 if (! display_debug_section (i, section, filedata))
17651 res = false;
17654 #ifdef ENABLE_LIBCTF
17655 if (dump & CTF_DUMP)
17657 if (! dump_section_as_ctf (section, filedata))
17658 res = false;
17660 #endif
17661 if (dump & SFRAME_DUMP)
17663 if (! dump_section_as_sframe (section, filedata))
17664 res = false;
17668 if (! filedata->is_separate)
17670 /* Check to see if the user requested a
17671 dump of a section that does not exist. */
17672 for (; i < filedata->dump.num_dump_sects; i++)
17673 if (filedata->dump.dump_sects[i])
17675 warn (_("Section %d was not dumped because it does not exist!\n"), i);
17676 res = false;
17680 return res;
17683 static void
17684 process_mips_fpe_exception (int mask)
17686 if (mask)
17688 bool first = true;
17690 if (mask & OEX_FPU_INEX)
17691 fputs ("INEX", stdout), first = false;
17692 if (mask & OEX_FPU_UFLO)
17693 printf ("%sUFLO", first ? "" : "|"), first = false;
17694 if (mask & OEX_FPU_OFLO)
17695 printf ("%sOFLO", first ? "" : "|"), first = false;
17696 if (mask & OEX_FPU_DIV0)
17697 printf ("%sDIV0", first ? "" : "|"), first = false;
17698 if (mask & OEX_FPU_INVAL)
17699 printf ("%sINVAL", first ? "" : "|");
17701 else
17702 fputs ("0", stdout);
17705 /* Display's the value of TAG at location P. If TAG is
17706 greater than 0 it is assumed to be an unknown tag, and
17707 a message is printed to this effect. Otherwise it is
17708 assumed that a message has already been printed.
17710 If the bottom bit of TAG is set it assumed to have a
17711 string value, otherwise it is assumed to have an integer
17712 value.
17714 Returns an updated P pointing to the first unread byte
17715 beyond the end of TAG's value.
17717 Reads at or beyond END will not be made. */
17719 static unsigned char *
17720 display_tag_value (signed int tag,
17721 unsigned char * p,
17722 const unsigned char * const end)
17724 uint64_t val;
17726 if (tag > 0)
17727 printf (" Tag_unknown_%d: ", tag);
17729 if (p >= end)
17731 warn (_("<corrupt tag>\n"));
17733 else if (tag & 1)
17735 /* PR 17531 file: 027-19978-0.004. */
17736 size_t maxlen = (end - p) - 1;
17738 putchar ('"');
17739 if (maxlen > 0)
17741 print_symbol_name ((int) maxlen, (const char *) p);
17742 p += strnlen ((char *) p, maxlen) + 1;
17744 else
17746 printf (_("<corrupt string tag>"));
17747 p = (unsigned char *) end;
17749 printf ("\"\n");
17751 else
17753 READ_ULEB (val, p, end);
17754 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
17757 assert (p <= end);
17758 return p;
17761 /* ARC ABI attributes section. */
17763 static unsigned char *
17764 display_arc_attribute (unsigned char * p,
17765 const unsigned char * const end)
17767 unsigned int tag;
17768 unsigned int val;
17770 READ_ULEB (tag, p, end);
17772 switch (tag)
17774 case Tag_ARC_PCS_config:
17775 READ_ULEB (val, p, end);
17776 printf (" Tag_ARC_PCS_config: ");
17777 switch (val)
17779 case 0:
17780 printf (_("Absent/Non standard\n"));
17781 break;
17782 case 1:
17783 printf (_("Bare metal/mwdt\n"));
17784 break;
17785 case 2:
17786 printf (_("Bare metal/newlib\n"));
17787 break;
17788 case 3:
17789 printf (_("Linux/uclibc\n"));
17790 break;
17791 case 4:
17792 printf (_("Linux/glibc\n"));
17793 break;
17794 default:
17795 printf (_("Unknown\n"));
17796 break;
17798 break;
17800 case Tag_ARC_CPU_base:
17801 READ_ULEB (val, p, end);
17802 printf (" Tag_ARC_CPU_base: ");
17803 switch (val)
17805 default:
17806 case TAG_CPU_NONE:
17807 printf (_("Absent\n"));
17808 break;
17809 case TAG_CPU_ARC6xx:
17810 printf ("ARC6xx\n");
17811 break;
17812 case TAG_CPU_ARC7xx:
17813 printf ("ARC7xx\n");
17814 break;
17815 case TAG_CPU_ARCEM:
17816 printf ("ARCEM\n");
17817 break;
17818 case TAG_CPU_ARCHS:
17819 printf ("ARCHS\n");
17820 break;
17822 break;
17824 case Tag_ARC_CPU_variation:
17825 READ_ULEB (val, p, end);
17826 printf (" Tag_ARC_CPU_variation: ");
17827 switch (val)
17829 default:
17830 if (val > 0 && val < 16)
17831 printf ("Core%d\n", val);
17832 else
17833 printf ("Unknown\n");
17834 break;
17836 case 0:
17837 printf (_("Absent\n"));
17838 break;
17840 break;
17842 case Tag_ARC_CPU_name:
17843 printf (" Tag_ARC_CPU_name: ");
17844 p = display_tag_value (-1, p, end);
17845 break;
17847 case Tag_ARC_ABI_rf16:
17848 READ_ULEB (val, p, end);
17849 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
17850 break;
17852 case Tag_ARC_ABI_osver:
17853 READ_ULEB (val, p, end);
17854 printf (" Tag_ARC_ABI_osver: v%d\n", val);
17855 break;
17857 case Tag_ARC_ABI_pic:
17858 case Tag_ARC_ABI_sda:
17859 READ_ULEB (val, p, end);
17860 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
17861 : " Tag_ARC_ABI_pic: ");
17862 switch (val)
17864 case 0:
17865 printf (_("Absent\n"));
17866 break;
17867 case 1:
17868 printf ("MWDT\n");
17869 break;
17870 case 2:
17871 printf ("GNU\n");
17872 break;
17873 default:
17874 printf (_("Unknown\n"));
17875 break;
17877 break;
17879 case Tag_ARC_ABI_tls:
17880 READ_ULEB (val, p, end);
17881 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
17882 break;
17884 case Tag_ARC_ABI_enumsize:
17885 READ_ULEB (val, p, end);
17886 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
17887 _("smallest"));
17888 break;
17890 case Tag_ARC_ABI_exceptions:
17891 READ_ULEB (val, p, end);
17892 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
17893 : _("default"));
17894 break;
17896 case Tag_ARC_ABI_double_size:
17897 READ_ULEB (val, p, end);
17898 printf (" Tag_ARC_ABI_double_size: %d\n", val);
17899 break;
17901 case Tag_ARC_ISA_config:
17902 printf (" Tag_ARC_ISA_config: ");
17903 p = display_tag_value (-1, p, end);
17904 break;
17906 case Tag_ARC_ISA_apex:
17907 printf (" Tag_ARC_ISA_apex: ");
17908 p = display_tag_value (-1, p, end);
17909 break;
17911 case Tag_ARC_ISA_mpy_option:
17912 READ_ULEB (val, p, end);
17913 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
17914 break;
17916 case Tag_ARC_ATR_version:
17917 READ_ULEB (val, p, end);
17918 printf (" Tag_ARC_ATR_version: %d\n", val);
17919 break;
17921 default:
17922 return display_tag_value (tag & 1, p, end);
17925 return p;
17928 /* ARM EABI attributes section. */
17929 typedef struct
17931 unsigned int tag;
17932 const char * name;
17933 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
17934 unsigned int type;
17935 const char *const *table;
17936 } arm_attr_public_tag;
17938 static const char *const arm_attr_tag_CPU_arch[] =
17939 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
17940 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
17941 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
17942 "v8.1-M.mainline", "v9"};
17943 static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
17944 static const char *const arm_attr_tag_THUMB_ISA_use[] =
17945 {"No", "Thumb-1", "Thumb-2", "Yes"};
17946 static const char *const arm_attr_tag_FP_arch[] =
17947 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
17948 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
17949 static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
17950 static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
17951 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
17952 "NEON for ARMv8.1"};
17953 static const char *const arm_attr_tag_PCS_config[] =
17954 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
17955 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
17956 static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
17957 {"V6", "SB", "TLS", "Unused"};
17958 static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
17959 {"Absolute", "PC-relative", "SB-relative", "None"};
17960 static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
17961 {"Absolute", "PC-relative", "None"};
17962 static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
17963 {"None", "direct", "GOT-indirect"};
17964 static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
17965 {"None", "??? 1", "2", "??? 3", "4"};
17966 static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
17967 static const char *const arm_attr_tag_ABI_FP_denormal[] =
17968 {"Unused", "Needed", "Sign only"};
17969 static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
17970 static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
17971 static const char *const arm_attr_tag_ABI_FP_number_model[] =
17972 {"Unused", "Finite", "RTABI", "IEEE 754"};
17973 static const char *const arm_attr_tag_ABI_enum_size[] =
17974 {"Unused", "small", "int", "forced to int"};
17975 static const char *const arm_attr_tag_ABI_HardFP_use[] =
17976 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
17977 static const char *const arm_attr_tag_ABI_VFP_args[] =
17978 {"AAPCS", "VFP registers", "custom", "compatible"};
17979 static const char *const arm_attr_tag_ABI_WMMX_args[] =
17980 {"AAPCS", "WMMX registers", "custom"};
17981 static const char *const arm_attr_tag_ABI_optimization_goals[] =
17982 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
17983 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
17984 static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
17985 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
17986 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
17987 static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
17988 static const char *const arm_attr_tag_FP_HP_extension[] =
17989 {"Not Allowed", "Allowed"};
17990 static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
17991 {"None", "IEEE 754", "Alternative Format"};
17992 static const char *const arm_attr_tag_DSP_extension[] =
17993 {"Follow architecture", "Allowed"};
17994 static const char *const arm_attr_tag_MPextension_use[] =
17995 {"Not Allowed", "Allowed"};
17996 static const char *const arm_attr_tag_DIV_use[] =
17997 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
17998 "Allowed in v7-A with integer division extension"};
17999 static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
18000 static const char *const arm_attr_tag_Virtualization_use[] =
18001 {"Not Allowed", "TrustZone", "Virtualization Extensions",
18002 "TrustZone and Virtualization Extensions"};
18003 static const char *const arm_attr_tag_MPextension_use_legacy[] =
18004 {"Not Allowed", "Allowed"};
18006 static const char *const arm_attr_tag_MVE_arch[] =
18007 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
18009 static const char * arm_attr_tag_PAC_extension[] =
18010 {"No PAC/AUT instructions",
18011 "PAC/AUT instructions permitted in the NOP space",
18012 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
18014 static const char * arm_attr_tag_BTI_extension[] =
18015 {"BTI instructions not permitted",
18016 "BTI instructions permitted in the NOP space",
18017 "BTI instructions permitted in the NOP and in the non-NOP space"};
18019 static const char * arm_attr_tag_BTI_use[] =
18020 {"Compiled without branch target enforcement",
18021 "Compiled with branch target enforcement"};
18023 static const char * arm_attr_tag_PACRET_use[] =
18024 {"Compiled without return address signing and authentication",
18025 "Compiled with return address signing and authentication"};
18027 #define LOOKUP(id, name) \
18028 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
18029 static arm_attr_public_tag arm_attr_public_tags[] =
18031 {4, "CPU_raw_name", 1, NULL},
18032 {5, "CPU_name", 1, NULL},
18033 LOOKUP(6, CPU_arch),
18034 {7, "CPU_arch_profile", 0, NULL},
18035 LOOKUP(8, ARM_ISA_use),
18036 LOOKUP(9, THUMB_ISA_use),
18037 LOOKUP(10, FP_arch),
18038 LOOKUP(11, WMMX_arch),
18039 LOOKUP(12, Advanced_SIMD_arch),
18040 LOOKUP(13, PCS_config),
18041 LOOKUP(14, ABI_PCS_R9_use),
18042 LOOKUP(15, ABI_PCS_RW_data),
18043 LOOKUP(16, ABI_PCS_RO_data),
18044 LOOKUP(17, ABI_PCS_GOT_use),
18045 LOOKUP(18, ABI_PCS_wchar_t),
18046 LOOKUP(19, ABI_FP_rounding),
18047 LOOKUP(20, ABI_FP_denormal),
18048 LOOKUP(21, ABI_FP_exceptions),
18049 LOOKUP(22, ABI_FP_user_exceptions),
18050 LOOKUP(23, ABI_FP_number_model),
18051 {24, "ABI_align_needed", 0, NULL},
18052 {25, "ABI_align_preserved", 0, NULL},
18053 LOOKUP(26, ABI_enum_size),
18054 LOOKUP(27, ABI_HardFP_use),
18055 LOOKUP(28, ABI_VFP_args),
18056 LOOKUP(29, ABI_WMMX_args),
18057 LOOKUP(30, ABI_optimization_goals),
18058 LOOKUP(31, ABI_FP_optimization_goals),
18059 {32, "compatibility", 0, NULL},
18060 LOOKUP(34, CPU_unaligned_access),
18061 LOOKUP(36, FP_HP_extension),
18062 LOOKUP(38, ABI_FP_16bit_format),
18063 LOOKUP(42, MPextension_use),
18064 LOOKUP(44, DIV_use),
18065 LOOKUP(46, DSP_extension),
18066 LOOKUP(48, MVE_arch),
18067 LOOKUP(50, PAC_extension),
18068 LOOKUP(52, BTI_extension),
18069 LOOKUP(74, BTI_use),
18070 LOOKUP(76, PACRET_use),
18071 {64, "nodefaults", 0, NULL},
18072 {65, "also_compatible_with", 0, NULL},
18073 LOOKUP(66, T2EE_use),
18074 {67, "conformance", 1, NULL},
18075 LOOKUP(68, Virtualization_use),
18076 LOOKUP(70, MPextension_use_legacy)
18078 #undef LOOKUP
18080 static unsigned char *
18081 display_arm_attribute (unsigned char * p,
18082 const unsigned char * const end)
18084 unsigned int tag;
18085 unsigned int val;
18086 arm_attr_public_tag * attr;
18087 unsigned i;
18088 unsigned int type;
18090 READ_ULEB (tag, p, end);
18091 attr = NULL;
18092 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
18094 if (arm_attr_public_tags[i].tag == tag)
18096 attr = &arm_attr_public_tags[i];
18097 break;
18101 if (attr)
18103 printf (" Tag_%s: ", attr->name);
18104 switch (attr->type)
18106 case 0:
18107 switch (tag)
18109 case 7: /* Tag_CPU_arch_profile. */
18110 READ_ULEB (val, p, end);
18111 switch (val)
18113 case 0: printf (_("None\n")); break;
18114 case 'A': printf (_("Application\n")); break;
18115 case 'R': printf (_("Realtime\n")); break;
18116 case 'M': printf (_("Microcontroller\n")); break;
18117 case 'S': printf (_("Application or Realtime\n")); break;
18118 default: printf ("??? (%d)\n", val); break;
18120 break;
18122 case 24: /* Tag_align_needed. */
18123 READ_ULEB (val, p, end);
18124 switch (val)
18126 case 0: printf (_("None\n")); break;
18127 case 1: printf (_("8-byte\n")); break;
18128 case 2: printf (_("4-byte\n")); break;
18129 case 3: printf ("??? 3\n"); break;
18130 default:
18131 if (val <= 12)
18132 printf (_("8-byte and up to %d-byte extended\n"),
18133 1 << val);
18134 else
18135 printf ("??? (%d)\n", val);
18136 break;
18138 break;
18140 case 25: /* Tag_align_preserved. */
18141 READ_ULEB (val, p, end);
18142 switch (val)
18144 case 0: printf (_("None\n")); break;
18145 case 1: printf (_("8-byte, except leaf SP\n")); break;
18146 case 2: printf (_("8-byte\n")); break;
18147 case 3: printf ("??? 3\n"); break;
18148 default:
18149 if (val <= 12)
18150 printf (_("8-byte and up to %d-byte extended\n"),
18151 1 << val);
18152 else
18153 printf ("??? (%d)\n", val);
18154 break;
18156 break;
18158 case 32: /* Tag_compatibility. */
18160 READ_ULEB (val, p, end);
18161 printf (_("flag = %d, vendor = "), val);
18162 if (p < end - 1)
18164 size_t maxlen = (end - p) - 1;
18166 print_symbol_name ((int) maxlen, (const char *) p);
18167 p += strnlen ((char *) p, maxlen) + 1;
18169 else
18171 printf (_("<corrupt>"));
18172 p = (unsigned char *) end;
18174 putchar ('\n');
18176 break;
18178 case 64: /* Tag_nodefaults. */
18179 /* PR 17531: file: 001-505008-0.01. */
18180 if (p < end)
18181 p++;
18182 printf (_("True\n"));
18183 break;
18185 case 65: /* Tag_also_compatible_with. */
18186 READ_ULEB (val, p, end);
18187 if (val == 6 /* Tag_CPU_arch. */)
18189 READ_ULEB (val, p, end);
18190 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
18191 printf ("??? (%d)\n", val);
18192 else
18193 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
18195 else
18196 printf ("???\n");
18197 while (p < end && *(p++) != '\0' /* NUL terminator. */)
18199 break;
18201 default:
18202 printf (_("<unknown: %d>\n"), tag);
18203 break;
18205 return p;
18207 case 1:
18208 return display_tag_value (-1, p, end);
18209 case 2:
18210 return display_tag_value (0, p, end);
18212 default:
18213 assert (attr->type & 0x80);
18214 READ_ULEB (val, p, end);
18215 type = attr->type & 0x7f;
18216 if (val >= type)
18217 printf ("??? (%d)\n", val);
18218 else
18219 printf ("%s\n", attr->table[val]);
18220 return p;
18224 return display_tag_value (tag, p, end);
18227 static unsigned char *
18228 display_gnu_attribute (unsigned char * p,
18229 unsigned char * (* display_proc_gnu_attribute)
18230 (unsigned char *, unsigned int, const unsigned char * const),
18231 const unsigned char * const end)
18233 unsigned int tag;
18234 unsigned int val;
18236 READ_ULEB (tag, p, end);
18238 /* Tag_compatibility is the only generic GNU attribute defined at
18239 present. */
18240 if (tag == 32)
18242 READ_ULEB (val, p, end);
18244 printf (_("flag = %d, vendor = "), val);
18245 if (p == end)
18247 printf (_("<corrupt>\n"));
18248 warn (_("corrupt vendor attribute\n"));
18250 else
18252 if (p < end - 1)
18254 size_t maxlen = (end - p) - 1;
18256 print_symbol_name ((int) maxlen, (const char *) p);
18257 p += strnlen ((char *) p, maxlen) + 1;
18259 else
18261 printf (_("<corrupt>"));
18262 p = (unsigned char *) end;
18264 putchar ('\n');
18266 return p;
18269 if ((tag & 2) == 0 && display_proc_gnu_attribute)
18270 return display_proc_gnu_attribute (p, tag, end);
18272 return display_tag_value (tag, p, end);
18275 static unsigned char *
18276 display_m68k_gnu_attribute (unsigned char * p,
18277 unsigned int tag,
18278 const unsigned char * const end)
18280 unsigned int val;
18282 if (tag == Tag_GNU_M68K_ABI_FP)
18284 printf (" Tag_GNU_M68K_ABI_FP: ");
18285 if (p == end)
18287 printf (_("<corrupt>\n"));
18288 return p;
18290 READ_ULEB (val, p, end);
18292 if (val > 3)
18293 printf ("(%#x), ", val);
18295 switch (val & 3)
18297 case 0:
18298 printf (_("unspecified hard/soft float\n"));
18299 break;
18300 case 1:
18301 printf (_("hard float\n"));
18302 break;
18303 case 2:
18304 printf (_("soft float\n"));
18305 break;
18307 return p;
18310 return display_tag_value (tag & 1, p, end);
18313 static unsigned char *
18314 display_power_gnu_attribute (unsigned char * p,
18315 unsigned int tag,
18316 const unsigned char * const end)
18318 unsigned int val;
18320 if (tag == Tag_GNU_Power_ABI_FP)
18322 printf (" Tag_GNU_Power_ABI_FP: ");
18323 if (p == end)
18325 printf (_("<corrupt>\n"));
18326 return p;
18328 READ_ULEB (val, p, end);
18330 if (val > 15)
18331 printf ("(%#x), ", val);
18333 switch (val & 3)
18335 case 0:
18336 printf (_("unspecified hard/soft float, "));
18337 break;
18338 case 1:
18339 printf (_("hard float, "));
18340 break;
18341 case 2:
18342 printf (_("soft float, "));
18343 break;
18344 case 3:
18345 printf (_("single-precision hard float, "));
18346 break;
18349 switch (val & 0xC)
18351 case 0:
18352 printf (_("unspecified long double\n"));
18353 break;
18354 case 4:
18355 printf (_("128-bit IBM long double\n"));
18356 break;
18357 case 8:
18358 printf (_("64-bit long double\n"));
18359 break;
18360 case 12:
18361 printf (_("128-bit IEEE long double\n"));
18362 break;
18364 return p;
18367 if (tag == Tag_GNU_Power_ABI_Vector)
18369 printf (" Tag_GNU_Power_ABI_Vector: ");
18370 if (p == end)
18372 printf (_("<corrupt>\n"));
18373 return p;
18375 READ_ULEB (val, p, end);
18377 if (val > 3)
18378 printf ("(%#x), ", val);
18380 switch (val & 3)
18382 case 0:
18383 printf (_("unspecified\n"));
18384 break;
18385 case 1:
18386 printf (_("generic\n"));
18387 break;
18388 case 2:
18389 printf ("AltiVec\n");
18390 break;
18391 case 3:
18392 printf ("SPE\n");
18393 break;
18395 return p;
18398 if (tag == Tag_GNU_Power_ABI_Struct_Return)
18400 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
18401 if (p == end)
18403 printf (_("<corrupt>\n"));
18404 return p;
18406 READ_ULEB (val, p, end);
18408 if (val > 2)
18409 printf ("(%#x), ", val);
18411 switch (val & 3)
18413 case 0:
18414 printf (_("unspecified\n"));
18415 break;
18416 case 1:
18417 printf ("r3/r4\n");
18418 break;
18419 case 2:
18420 printf (_("memory\n"));
18421 break;
18422 case 3:
18423 printf ("???\n");
18424 break;
18426 return p;
18429 return display_tag_value (tag & 1, p, end);
18432 static unsigned char *
18433 display_s390_gnu_attribute (unsigned char * p,
18434 unsigned int tag,
18435 const unsigned char * const end)
18437 unsigned int val;
18439 if (tag == Tag_GNU_S390_ABI_Vector)
18441 printf (" Tag_GNU_S390_ABI_Vector: ");
18442 READ_ULEB (val, p, end);
18444 switch (val)
18446 case 0:
18447 printf (_("any\n"));
18448 break;
18449 case 1:
18450 printf (_("software\n"));
18451 break;
18452 case 2:
18453 printf (_("hardware\n"));
18454 break;
18455 default:
18456 printf ("??? (%d)\n", val);
18457 break;
18459 return p;
18462 return display_tag_value (tag & 1, p, end);
18465 static void
18466 display_sparc_hwcaps (unsigned int mask)
18468 if (mask)
18470 bool first = true;
18472 if (mask & ELF_SPARC_HWCAP_MUL32)
18473 fputs ("mul32", stdout), first = false;
18474 if (mask & ELF_SPARC_HWCAP_DIV32)
18475 printf ("%sdiv32", first ? "" : "|"), first = false;
18476 if (mask & ELF_SPARC_HWCAP_FSMULD)
18477 printf ("%sfsmuld", first ? "" : "|"), first = false;
18478 if (mask & ELF_SPARC_HWCAP_V8PLUS)
18479 printf ("%sv8plus", first ? "" : "|"), first = false;
18480 if (mask & ELF_SPARC_HWCAP_POPC)
18481 printf ("%spopc", first ? "" : "|"), first = false;
18482 if (mask & ELF_SPARC_HWCAP_VIS)
18483 printf ("%svis", first ? "" : "|"), first = false;
18484 if (mask & ELF_SPARC_HWCAP_VIS2)
18485 printf ("%svis2", first ? "" : "|"), first = false;
18486 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
18487 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
18488 if (mask & ELF_SPARC_HWCAP_FMAF)
18489 printf ("%sfmaf", first ? "" : "|"), first = false;
18490 if (mask & ELF_SPARC_HWCAP_VIS3)
18491 printf ("%svis3", first ? "" : "|"), first = false;
18492 if (mask & ELF_SPARC_HWCAP_HPC)
18493 printf ("%shpc", first ? "" : "|"), first = false;
18494 if (mask & ELF_SPARC_HWCAP_RANDOM)
18495 printf ("%srandom", first ? "" : "|"), first = false;
18496 if (mask & ELF_SPARC_HWCAP_TRANS)
18497 printf ("%strans", first ? "" : "|"), first = false;
18498 if (mask & ELF_SPARC_HWCAP_FJFMAU)
18499 printf ("%sfjfmau", first ? "" : "|"), first = false;
18500 if (mask & ELF_SPARC_HWCAP_IMA)
18501 printf ("%sima", first ? "" : "|"), first = false;
18502 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
18503 printf ("%scspare", first ? "" : "|"), first = false;
18505 else
18506 fputc ('0', stdout);
18507 fputc ('\n', stdout);
18510 static void
18511 display_sparc_hwcaps2 (unsigned int mask)
18513 if (mask)
18515 bool first = true;
18517 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
18518 fputs ("fjathplus", stdout), first = false;
18519 if (mask & ELF_SPARC_HWCAP2_VIS3B)
18520 printf ("%svis3b", first ? "" : "|"), first = false;
18521 if (mask & ELF_SPARC_HWCAP2_ADP)
18522 printf ("%sadp", first ? "" : "|"), first = false;
18523 if (mask & ELF_SPARC_HWCAP2_SPARC5)
18524 printf ("%ssparc5", first ? "" : "|"), first = false;
18525 if (mask & ELF_SPARC_HWCAP2_MWAIT)
18526 printf ("%smwait", first ? "" : "|"), first = false;
18527 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
18528 printf ("%sxmpmul", first ? "" : "|"), first = false;
18529 if (mask & ELF_SPARC_HWCAP2_XMONT)
18530 printf ("%sxmont2", first ? "" : "|"), first = false;
18531 if (mask & ELF_SPARC_HWCAP2_NSEC)
18532 printf ("%snsec", first ? "" : "|"), first = false;
18533 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
18534 printf ("%sfjathhpc", first ? "" : "|"), first = false;
18535 if (mask & ELF_SPARC_HWCAP2_FJDES)
18536 printf ("%sfjdes", first ? "" : "|"), first = false;
18537 if (mask & ELF_SPARC_HWCAP2_FJAES)
18538 printf ("%sfjaes", first ? "" : "|"), first = false;
18540 else
18541 fputc ('0', stdout);
18542 fputc ('\n', stdout);
18545 static unsigned char *
18546 display_sparc_gnu_attribute (unsigned char * p,
18547 unsigned int tag,
18548 const unsigned char * const end)
18550 unsigned int val;
18552 if (tag == Tag_GNU_Sparc_HWCAPS)
18554 READ_ULEB (val, p, end);
18555 printf (" Tag_GNU_Sparc_HWCAPS: ");
18556 display_sparc_hwcaps (val);
18557 return p;
18559 if (tag == Tag_GNU_Sparc_HWCAPS2)
18561 READ_ULEB (val, p, end);
18562 printf (" Tag_GNU_Sparc_HWCAPS2: ");
18563 display_sparc_hwcaps2 (val);
18564 return p;
18567 return display_tag_value (tag, p, end);
18570 static void
18571 print_mips_fp_abi_value (unsigned int val)
18573 switch (val)
18575 case Val_GNU_MIPS_ABI_FP_ANY:
18576 printf (_("Hard or soft float\n"));
18577 break;
18578 case Val_GNU_MIPS_ABI_FP_DOUBLE:
18579 printf (_("Hard float (double precision)\n"));
18580 break;
18581 case Val_GNU_MIPS_ABI_FP_SINGLE:
18582 printf (_("Hard float (single precision)\n"));
18583 break;
18584 case Val_GNU_MIPS_ABI_FP_SOFT:
18585 printf (_("Soft float\n"));
18586 break;
18587 case Val_GNU_MIPS_ABI_FP_OLD_64:
18588 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
18589 break;
18590 case Val_GNU_MIPS_ABI_FP_XX:
18591 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
18592 break;
18593 case Val_GNU_MIPS_ABI_FP_64:
18594 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
18595 break;
18596 case Val_GNU_MIPS_ABI_FP_64A:
18597 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
18598 break;
18599 case Val_GNU_MIPS_ABI_FP_NAN2008:
18600 printf (_("NaN 2008 compatibility\n"));
18601 break;
18602 default:
18603 printf ("??? (%d)\n", val);
18604 break;
18608 static unsigned char *
18609 display_mips_gnu_attribute (unsigned char * p,
18610 unsigned int tag,
18611 const unsigned char * const end)
18613 if (tag == Tag_GNU_MIPS_ABI_FP)
18615 unsigned int val;
18617 printf (" Tag_GNU_MIPS_ABI_FP: ");
18618 READ_ULEB (val, p, end);
18619 print_mips_fp_abi_value (val);
18620 return p;
18623 if (tag == Tag_GNU_MIPS_ABI_MSA)
18625 unsigned int val;
18627 printf (" Tag_GNU_MIPS_ABI_MSA: ");
18628 READ_ULEB (val, p, end);
18630 switch (val)
18632 case Val_GNU_MIPS_ABI_MSA_ANY:
18633 printf (_("Any MSA or not\n"));
18634 break;
18635 case Val_GNU_MIPS_ABI_MSA_128:
18636 printf (_("128-bit MSA\n"));
18637 break;
18638 default:
18639 printf ("??? (%d)\n", val);
18640 break;
18642 return p;
18645 return display_tag_value (tag & 1, p, end);
18648 static unsigned char *
18649 display_tic6x_attribute (unsigned char * p,
18650 const unsigned char * const end)
18652 unsigned int tag;
18653 unsigned int val;
18655 READ_ULEB (tag, p, end);
18657 switch (tag)
18659 case Tag_ISA:
18660 printf (" Tag_ISA: ");
18661 READ_ULEB (val, p, end);
18663 switch (val)
18665 case C6XABI_Tag_ISA_none:
18666 printf (_("None\n"));
18667 break;
18668 case C6XABI_Tag_ISA_C62X:
18669 printf ("C62x\n");
18670 break;
18671 case C6XABI_Tag_ISA_C67X:
18672 printf ("C67x\n");
18673 break;
18674 case C6XABI_Tag_ISA_C67XP:
18675 printf ("C67x+\n");
18676 break;
18677 case C6XABI_Tag_ISA_C64X:
18678 printf ("C64x\n");
18679 break;
18680 case C6XABI_Tag_ISA_C64XP:
18681 printf ("C64x+\n");
18682 break;
18683 case C6XABI_Tag_ISA_C674X:
18684 printf ("C674x\n");
18685 break;
18686 default:
18687 printf ("??? (%d)\n", val);
18688 break;
18690 return p;
18692 case Tag_ABI_wchar_t:
18693 printf (" Tag_ABI_wchar_t: ");
18694 READ_ULEB (val, p, end);
18695 switch (val)
18697 case 0:
18698 printf (_("Not used\n"));
18699 break;
18700 case 1:
18701 printf (_("2 bytes\n"));
18702 break;
18703 case 2:
18704 printf (_("4 bytes\n"));
18705 break;
18706 default:
18707 printf ("??? (%d)\n", val);
18708 break;
18710 return p;
18712 case Tag_ABI_stack_align_needed:
18713 printf (" Tag_ABI_stack_align_needed: ");
18714 READ_ULEB (val, p, end);
18715 switch (val)
18717 case 0:
18718 printf (_("8-byte\n"));
18719 break;
18720 case 1:
18721 printf (_("16-byte\n"));
18722 break;
18723 default:
18724 printf ("??? (%d)\n", val);
18725 break;
18727 return p;
18729 case Tag_ABI_stack_align_preserved:
18730 READ_ULEB (val, p, end);
18731 printf (" Tag_ABI_stack_align_preserved: ");
18732 switch (val)
18734 case 0:
18735 printf (_("8-byte\n"));
18736 break;
18737 case 1:
18738 printf (_("16-byte\n"));
18739 break;
18740 default:
18741 printf ("??? (%d)\n", val);
18742 break;
18744 return p;
18746 case Tag_ABI_DSBT:
18747 READ_ULEB (val, p, end);
18748 printf (" Tag_ABI_DSBT: ");
18749 switch (val)
18751 case 0:
18752 printf (_("DSBT addressing not used\n"));
18753 break;
18754 case 1:
18755 printf (_("DSBT addressing used\n"));
18756 break;
18757 default:
18758 printf ("??? (%d)\n", val);
18759 break;
18761 return p;
18763 case Tag_ABI_PID:
18764 READ_ULEB (val, p, end);
18765 printf (" Tag_ABI_PID: ");
18766 switch (val)
18768 case 0:
18769 printf (_("Data addressing position-dependent\n"));
18770 break;
18771 case 1:
18772 printf (_("Data addressing position-independent, GOT near DP\n"));
18773 break;
18774 case 2:
18775 printf (_("Data addressing position-independent, GOT far from DP\n"));
18776 break;
18777 default:
18778 printf ("??? (%d)\n", val);
18779 break;
18781 return p;
18783 case Tag_ABI_PIC:
18784 READ_ULEB (val, p, end);
18785 printf (" Tag_ABI_PIC: ");
18786 switch (val)
18788 case 0:
18789 printf (_("Code addressing position-dependent\n"));
18790 break;
18791 case 1:
18792 printf (_("Code addressing position-independent\n"));
18793 break;
18794 default:
18795 printf ("??? (%d)\n", val);
18796 break;
18798 return p;
18800 case Tag_ABI_array_object_alignment:
18801 READ_ULEB (val, p, end);
18802 printf (" Tag_ABI_array_object_alignment: ");
18803 switch (val)
18805 case 0:
18806 printf (_("8-byte\n"));
18807 break;
18808 case 1:
18809 printf (_("4-byte\n"));
18810 break;
18811 case 2:
18812 printf (_("16-byte\n"));
18813 break;
18814 default:
18815 printf ("??? (%d)\n", val);
18816 break;
18818 return p;
18820 case Tag_ABI_array_object_align_expected:
18821 READ_ULEB (val, p, end);
18822 printf (" Tag_ABI_array_object_align_expected: ");
18823 switch (val)
18825 case 0:
18826 printf (_("8-byte\n"));
18827 break;
18828 case 1:
18829 printf (_("4-byte\n"));
18830 break;
18831 case 2:
18832 printf (_("16-byte\n"));
18833 break;
18834 default:
18835 printf ("??? (%d)\n", val);
18836 break;
18838 return p;
18840 case Tag_ABI_compatibility:
18842 READ_ULEB (val, p, end);
18843 printf (" Tag_ABI_compatibility: ");
18844 printf (_("flag = %d, vendor = "), val);
18845 if (p < end - 1)
18847 size_t maxlen = (end - p) - 1;
18849 print_symbol_name ((int) maxlen, (const char *) p);
18850 p += strnlen ((char *) p, maxlen) + 1;
18852 else
18854 printf (_("<corrupt>"));
18855 p = (unsigned char *) end;
18857 putchar ('\n');
18858 return p;
18861 case Tag_ABI_conformance:
18863 printf (" Tag_ABI_conformance: \"");
18864 if (p < end - 1)
18866 size_t maxlen = (end - p) - 1;
18868 print_symbol_name ((int) maxlen, (const char *) p);
18869 p += strnlen ((char *) p, maxlen) + 1;
18871 else
18873 printf (_("<corrupt>"));
18874 p = (unsigned char *) end;
18876 printf ("\"\n");
18877 return p;
18881 return display_tag_value (tag, p, end);
18884 static void
18885 display_raw_attribute (unsigned char * p, unsigned char const * const end)
18887 uint64_t addr = 0;
18888 size_t bytes = end - p;
18890 assert (end >= p);
18891 while (bytes)
18893 int j;
18894 int k;
18895 int lbytes = (bytes > 16 ? 16 : bytes);
18897 printf (" 0x%8.8" PRIx64 " ", addr);
18899 for (j = 0; j < 16; j++)
18901 if (j < lbytes)
18902 printf ("%2.2x", p[j]);
18903 else
18904 printf (" ");
18906 if ((j & 3) == 3)
18907 printf (" ");
18910 for (j = 0; j < lbytes; j++)
18912 k = p[j];
18913 if (k >= ' ' && k < 0x7f)
18914 printf ("%c", k);
18915 else
18916 printf (".");
18919 putchar ('\n');
18921 p += lbytes;
18922 bytes -= lbytes;
18923 addr += lbytes;
18926 putchar ('\n');
18929 static unsigned char *
18930 display_msp430_attribute (unsigned char * p,
18931 const unsigned char * const end)
18933 uint64_t val;
18934 uint64_t tag;
18936 READ_ULEB (tag, p, end);
18938 switch (tag)
18940 case OFBA_MSPABI_Tag_ISA:
18941 printf (" Tag_ISA: ");
18942 READ_ULEB (val, p, end);
18943 switch (val)
18945 case 0: printf (_("None\n")); break;
18946 case 1: printf (_("MSP430\n")); break;
18947 case 2: printf (_("MSP430X\n")); break;
18948 default: printf ("??? (%" PRId64 ")\n", val); break;
18950 break;
18952 case OFBA_MSPABI_Tag_Code_Model:
18953 printf (" Tag_Code_Model: ");
18954 READ_ULEB (val, p, end);
18955 switch (val)
18957 case 0: printf (_("None\n")); break;
18958 case 1: printf (_("Small\n")); break;
18959 case 2: printf (_("Large\n")); break;
18960 default: printf ("??? (%" PRId64 ")\n", val); break;
18962 break;
18964 case OFBA_MSPABI_Tag_Data_Model:
18965 printf (" Tag_Data_Model: ");
18966 READ_ULEB (val, p, end);
18967 switch (val)
18969 case 0: printf (_("None\n")); break;
18970 case 1: printf (_("Small\n")); break;
18971 case 2: printf (_("Large\n")); break;
18972 case 3: printf (_("Restricted Large\n")); break;
18973 default: printf ("??? (%" PRId64 ")\n", val); break;
18975 break;
18977 default:
18978 printf (_(" <unknown tag %" PRId64 ">: "), tag);
18980 if (tag & 1)
18982 putchar ('"');
18983 if (p < end - 1)
18985 size_t maxlen = (end - p) - 1;
18987 print_symbol_name ((int) maxlen, (const char *) p);
18988 p += strnlen ((char *) p, maxlen) + 1;
18990 else
18992 printf (_("<corrupt>"));
18993 p = (unsigned char *) end;
18995 printf ("\"\n");
18997 else
18999 READ_ULEB (val, p, end);
19000 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
19002 break;
19005 assert (p <= end);
19006 return p;
19009 static unsigned char *
19010 display_msp430_gnu_attribute (unsigned char * p,
19011 unsigned int tag,
19012 const unsigned char * const end)
19014 if (tag == Tag_GNU_MSP430_Data_Region)
19016 uint64_t val;
19018 printf (" Tag_GNU_MSP430_Data_Region: ");
19019 READ_ULEB (val, p, end);
19021 switch (val)
19023 case Val_GNU_MSP430_Data_Region_Any:
19024 printf (_("Any Region\n"));
19025 break;
19026 case Val_GNU_MSP430_Data_Region_Lower:
19027 printf (_("Lower Region Only\n"));
19028 break;
19029 default:
19030 printf ("??? (%" PRIu64 ")\n", val);
19032 return p;
19034 return display_tag_value (tag & 1, p, end);
19037 struct riscv_attr_tag_t {
19038 const char *name;
19039 unsigned int tag;
19042 static struct riscv_attr_tag_t riscv_attr_tag[] =
19044 #define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
19045 T(arch),
19046 T(priv_spec),
19047 T(priv_spec_minor),
19048 T(priv_spec_revision),
19049 T(unaligned_access),
19050 T(stack_align),
19051 #undef T
19054 static unsigned char *
19055 display_riscv_attribute (unsigned char *p,
19056 const unsigned char * const end)
19058 uint64_t val;
19059 uint64_t tag;
19060 struct riscv_attr_tag_t *attr = NULL;
19061 unsigned i;
19063 READ_ULEB (tag, p, end);
19065 /* Find the name of attribute. */
19066 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
19068 if (riscv_attr_tag[i].tag == tag)
19070 attr = &riscv_attr_tag[i];
19071 break;
19075 if (attr)
19076 printf (" %s: ", attr->name);
19077 else
19078 return display_tag_value (tag, p, end);
19080 switch (tag)
19082 case Tag_RISCV_priv_spec:
19083 case Tag_RISCV_priv_spec_minor:
19084 case Tag_RISCV_priv_spec_revision:
19085 READ_ULEB (val, p, end);
19086 printf ("%" PRIu64 "\n", val);
19087 break;
19088 case Tag_RISCV_unaligned_access:
19089 READ_ULEB (val, p, end);
19090 switch (val)
19092 case 0:
19093 printf (_("No unaligned access\n"));
19094 break;
19095 case 1:
19096 printf (_("Unaligned access\n"));
19097 break;
19099 break;
19100 case Tag_RISCV_stack_align:
19101 READ_ULEB (val, p, end);
19102 printf (_("%" PRIu64 "-bytes\n"), val);
19103 break;
19104 case Tag_RISCV_arch:
19105 p = display_tag_value (-1, p, end);
19106 break;
19107 default:
19108 return display_tag_value (tag, p, end);
19111 return p;
19114 static unsigned char *
19115 display_csky_attribute (unsigned char * p,
19116 const unsigned char * const end)
19118 uint64_t tag;
19119 uint64_t val;
19120 READ_ULEB (tag, p, end);
19122 if (tag >= Tag_CSKY_MAX)
19124 return display_tag_value (-1, p, end);
19127 switch (tag)
19129 case Tag_CSKY_ARCH_NAME:
19130 printf (" Tag_CSKY_ARCH_NAME:\t\t");
19131 return display_tag_value (-1, p, end);
19132 case Tag_CSKY_CPU_NAME:
19133 printf (" Tag_CSKY_CPU_NAME:\t\t");
19134 return display_tag_value (-1, p, end);
19136 case Tag_CSKY_ISA_FLAGS:
19137 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
19138 return display_tag_value (0, p, end);
19139 case Tag_CSKY_ISA_EXT_FLAGS:
19140 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
19141 return display_tag_value (0, p, end);
19143 case Tag_CSKY_DSP_VERSION:
19144 printf (" Tag_CSKY_DSP_VERSION:\t\t");
19145 READ_ULEB (val, p, end);
19146 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
19147 printf ("DSP Extension\n");
19148 else if (val == VAL_CSKY_DSP_VERSION_2)
19149 printf ("DSP 2.0\n");
19150 break;
19152 case Tag_CSKY_VDSP_VERSION:
19153 printf (" Tag_CSKY_VDSP_VERSION:\t");
19154 READ_ULEB (val, p, end);
19155 printf ("VDSP Version %" PRId64 "\n", val);
19156 break;
19158 case Tag_CSKY_FPU_VERSION:
19159 printf (" Tag_CSKY_FPU_VERSION:\t\t");
19160 READ_ULEB (val, p, end);
19161 if (val == VAL_CSKY_FPU_VERSION_1)
19162 printf ("ABIV1 FPU Version 1\n");
19163 else if (val == VAL_CSKY_FPU_VERSION_2)
19164 printf ("FPU Version 2\n");
19165 break;
19167 case Tag_CSKY_FPU_ABI:
19168 printf (" Tag_CSKY_FPU_ABI:\t\t");
19169 READ_ULEB (val, p, end);
19170 if (val == VAL_CSKY_FPU_ABI_HARD)
19171 printf ("Hard\n");
19172 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
19173 printf ("SoftFP\n");
19174 else if (val == VAL_CSKY_FPU_ABI_SOFT)
19175 printf ("Soft\n");
19176 break;
19177 case Tag_CSKY_FPU_ROUNDING:
19178 READ_ULEB (val, p, end);
19179 if (val == 1)
19181 printf (" Tag_CSKY_FPU_ROUNDING:\t");
19182 printf ("Needed\n");
19184 break;
19185 case Tag_CSKY_FPU_DENORMAL:
19186 READ_ULEB (val, p, end);
19187 if (val == 1)
19189 printf (" Tag_CSKY_FPU_DENORMAL:\t");
19190 printf ("Needed\n");
19192 break;
19193 case Tag_CSKY_FPU_Exception:
19194 READ_ULEB (val, p, end);
19195 if (val == 1)
19197 printf (" Tag_CSKY_FPU_Exception:\t");
19198 printf ("Needed\n");
19200 break;
19201 case Tag_CSKY_FPU_NUMBER_MODULE:
19202 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
19203 return display_tag_value (-1, p, end);
19204 case Tag_CSKY_FPU_HARDFP:
19205 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
19206 READ_ULEB (val, p, end);
19207 if (val & VAL_CSKY_FPU_HARDFP_HALF)
19208 printf (" Half");
19209 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
19210 printf (" Single");
19211 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
19212 printf (" Double");
19213 printf ("\n");
19214 break;
19215 default:
19216 return display_tag_value (tag, p, end);
19218 return p;
19221 static bool
19222 process_attributes (Filedata * filedata,
19223 const char * public_name,
19224 unsigned int proc_type,
19225 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
19226 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
19228 Elf_Internal_Shdr * sect;
19229 unsigned i;
19230 bool res = true;
19232 /* Find the section header so that we get the size. */
19233 for (i = 0, sect = filedata->section_headers;
19234 i < filedata->file_header.e_shnum;
19235 i++, sect++)
19237 unsigned char * contents;
19238 unsigned char * p;
19240 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
19241 continue;
19243 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
19244 sect->sh_size, _("attributes"));
19245 if (contents == NULL)
19247 res = false;
19248 continue;
19251 p = contents;
19252 /* The first character is the version of the attributes.
19253 Currently only version 1, (aka 'A') is recognised here. */
19254 if (*p != 'A')
19256 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
19257 res = false;
19259 else
19261 uint64_t section_len;
19263 section_len = sect->sh_size - 1;
19264 p++;
19266 while (section_len > 0)
19268 uint64_t attr_len;
19269 unsigned int namelen;
19270 bool public_section;
19271 bool gnu_section;
19273 if (section_len <= 4)
19275 error (_("Tag section ends prematurely\n"));
19276 res = false;
19277 break;
19279 attr_len = byte_get (p, 4);
19280 p += 4;
19282 if (attr_len > section_len)
19284 error (_("Bad attribute length (%u > %u)\n"),
19285 (unsigned) attr_len, (unsigned) section_len);
19286 attr_len = section_len;
19287 res = false;
19289 /* PR 17531: file: 001-101425-0.004 */
19290 else if (attr_len < 5)
19292 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
19293 res = false;
19294 break;
19297 section_len -= attr_len;
19298 attr_len -= 4;
19300 namelen = strnlen ((char *) p, attr_len) + 1;
19301 if (namelen == 0 || namelen >= attr_len)
19303 error (_("Corrupt attribute section name\n"));
19304 res = false;
19305 break;
19308 printf (_("Attribute Section: "));
19309 print_symbol_name (INT_MAX, (const char *) p);
19310 putchar ('\n');
19312 if (public_name && streq ((char *) p, public_name))
19313 public_section = true;
19314 else
19315 public_section = false;
19317 if (streq ((char *) p, "gnu"))
19318 gnu_section = true;
19319 else
19320 gnu_section = false;
19322 p += namelen;
19323 attr_len -= namelen;
19325 while (attr_len > 0 && p < contents + sect->sh_size)
19327 int tag;
19328 unsigned int val;
19329 uint64_t size;
19330 unsigned char * end;
19332 /* PR binutils/17531: Safe handling of corrupt files. */
19333 if (attr_len < 6)
19335 error (_("Unused bytes at end of section\n"));
19336 res = false;
19337 section_len = 0;
19338 break;
19341 tag = *(p++);
19342 size = byte_get (p, 4);
19343 if (size > attr_len)
19345 error (_("Bad subsection length (%u > %u)\n"),
19346 (unsigned) size, (unsigned) attr_len);
19347 res = false;
19348 size = attr_len;
19350 /* PR binutils/17531: Safe handling of corrupt files. */
19351 if (size < 6)
19353 error (_("Bad subsection length (%u < 6)\n"),
19354 (unsigned) size);
19355 res = false;
19356 section_len = 0;
19357 break;
19360 attr_len -= size;
19361 end = p + size - 1;
19362 assert (end <= contents + sect->sh_size);
19363 p += 4;
19365 switch (tag)
19367 case 1:
19368 printf (_("File Attributes\n"));
19369 break;
19370 case 2:
19371 printf (_("Section Attributes:"));
19372 goto do_numlist;
19373 case 3:
19374 printf (_("Symbol Attributes:"));
19375 /* Fall through. */
19376 do_numlist:
19377 for (;;)
19379 READ_ULEB (val, p, end);
19380 if (val == 0)
19381 break;
19382 printf (" %d", val);
19384 printf ("\n");
19385 break;
19386 default:
19387 printf (_("Unknown tag: %d\n"), tag);
19388 public_section = false;
19389 break;
19392 if (public_section && display_pub_attribute != NULL)
19394 while (p < end)
19395 p = display_pub_attribute (p, end);
19396 assert (p == end);
19398 else if (gnu_section && display_proc_gnu_attribute != NULL)
19400 while (p < end)
19401 p = display_gnu_attribute (p,
19402 display_proc_gnu_attribute,
19403 end);
19404 assert (p == end);
19406 else if (p < end)
19408 printf (_(" Unknown attribute:\n"));
19409 display_raw_attribute (p, end);
19410 p = end;
19412 else
19413 attr_len = 0;
19418 free (contents);
19421 return res;
19424 /* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
19425 Print the Address, Access and Initial fields of an entry at VMA ADDR
19426 and return the VMA of the next entry, or -1 if there was a problem.
19427 Does not read from DATA_END or beyond. */
19429 static uint64_t
19430 print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
19431 unsigned char * data_end)
19433 printf (" ");
19434 print_vma (addr, LONG_HEX);
19435 printf (" ");
19436 if (addr < pltgot + 0xfff0)
19437 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
19438 else
19439 printf ("%10s", "");
19440 printf (" ");
19441 if (data == NULL)
19442 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
19443 else
19445 uint64_t entry;
19446 unsigned char * from = data + addr - pltgot;
19448 if (from + (is_32bit_elf ? 4 : 8) > data_end)
19450 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
19451 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
19452 return (uint64_t) -1;
19454 else
19456 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
19457 print_vma (entry, LONG_HEX);
19460 return addr + (is_32bit_elf ? 4 : 8);
19463 /* DATA points to the contents of a MIPS PLT GOT that starts at VMA
19464 PLTGOT. Print the Address and Initial fields of an entry at VMA
19465 ADDR and return the VMA of the next entry. */
19467 static uint64_t
19468 print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
19470 printf (" ");
19471 print_vma (addr, LONG_HEX);
19472 printf (" ");
19473 if (data == NULL)
19474 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
19475 else
19477 uint64_t entry;
19479 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
19480 print_vma (entry, LONG_HEX);
19482 return addr + (is_32bit_elf ? 4 : 8);
19485 static void
19486 print_mips_ases (unsigned int mask)
19488 if (mask & AFL_ASE_DSP)
19489 fputs ("\n\tDSP ASE", stdout);
19490 if (mask & AFL_ASE_DSPR2)
19491 fputs ("\n\tDSP R2 ASE", stdout);
19492 if (mask & AFL_ASE_DSPR3)
19493 fputs ("\n\tDSP R3 ASE", stdout);
19494 if (mask & AFL_ASE_EVA)
19495 fputs ("\n\tEnhanced VA Scheme", stdout);
19496 if (mask & AFL_ASE_MCU)
19497 fputs ("\n\tMCU (MicroController) ASE", stdout);
19498 if (mask & AFL_ASE_MDMX)
19499 fputs ("\n\tMDMX ASE", stdout);
19500 if (mask & AFL_ASE_MIPS3D)
19501 fputs ("\n\tMIPS-3D ASE", stdout);
19502 if (mask & AFL_ASE_MT)
19503 fputs ("\n\tMT ASE", stdout);
19504 if (mask & AFL_ASE_SMARTMIPS)
19505 fputs ("\n\tSmartMIPS ASE", stdout);
19506 if (mask & AFL_ASE_VIRT)
19507 fputs ("\n\tVZ ASE", stdout);
19508 if (mask & AFL_ASE_MSA)
19509 fputs ("\n\tMSA ASE", stdout);
19510 if (mask & AFL_ASE_MIPS16)
19511 fputs ("\n\tMIPS16 ASE", stdout);
19512 if (mask & AFL_ASE_MICROMIPS)
19513 fputs ("\n\tMICROMIPS ASE", stdout);
19514 if (mask & AFL_ASE_XPA)
19515 fputs ("\n\tXPA ASE", stdout);
19516 if (mask & AFL_ASE_MIPS16E2)
19517 fputs ("\n\tMIPS16e2 ASE", stdout);
19518 if (mask & AFL_ASE_CRC)
19519 fputs ("\n\tCRC ASE", stdout);
19520 if (mask & AFL_ASE_GINV)
19521 fputs ("\n\tGINV ASE", stdout);
19522 if (mask & AFL_ASE_LOONGSON_MMI)
19523 fputs ("\n\tLoongson MMI ASE", stdout);
19524 if (mask & AFL_ASE_LOONGSON_CAM)
19525 fputs ("\n\tLoongson CAM ASE", stdout);
19526 if (mask & AFL_ASE_LOONGSON_EXT)
19527 fputs ("\n\tLoongson EXT ASE", stdout);
19528 if (mask & AFL_ASE_LOONGSON_EXT2)
19529 fputs ("\n\tLoongson EXT2 ASE", stdout);
19530 if (mask == 0)
19531 fprintf (stdout, "\n\t%s", _("None"));
19532 else if ((mask & ~AFL_ASE_MASK) != 0)
19533 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
19536 static void
19537 print_mips_isa_ext (unsigned int isa_ext)
19539 switch (isa_ext)
19541 case 0:
19542 fputs (_("None"), stdout);
19543 break;
19544 case AFL_EXT_XLR:
19545 fputs ("RMI XLR", stdout);
19546 break;
19547 case AFL_EXT_OCTEON3:
19548 fputs ("Cavium Networks Octeon3", stdout);
19549 break;
19550 case AFL_EXT_OCTEON2:
19551 fputs ("Cavium Networks Octeon2", stdout);
19552 break;
19553 case AFL_EXT_OCTEONP:
19554 fputs ("Cavium Networks OcteonP", stdout);
19555 break;
19556 case AFL_EXT_OCTEON:
19557 fputs ("Cavium Networks Octeon", stdout);
19558 break;
19559 case AFL_EXT_5900:
19560 fputs ("Toshiba R5900", stdout);
19561 break;
19562 case AFL_EXT_4650:
19563 fputs ("MIPS R4650", stdout);
19564 break;
19565 case AFL_EXT_4010:
19566 fputs ("LSI R4010", stdout);
19567 break;
19568 case AFL_EXT_4100:
19569 fputs ("NEC VR4100", stdout);
19570 break;
19571 case AFL_EXT_3900:
19572 fputs ("Toshiba R3900", stdout);
19573 break;
19574 case AFL_EXT_10000:
19575 fputs ("MIPS R10000", stdout);
19576 break;
19577 case AFL_EXT_SB1:
19578 fputs ("Broadcom SB-1", stdout);
19579 break;
19580 case AFL_EXT_4111:
19581 fputs ("NEC VR4111/VR4181", stdout);
19582 break;
19583 case AFL_EXT_4120:
19584 fputs ("NEC VR4120", stdout);
19585 break;
19586 case AFL_EXT_5400:
19587 fputs ("NEC VR5400", stdout);
19588 break;
19589 case AFL_EXT_5500:
19590 fputs ("NEC VR5500", stdout);
19591 break;
19592 case AFL_EXT_LOONGSON_2E:
19593 fputs ("ST Microelectronics Loongson 2E", stdout);
19594 break;
19595 case AFL_EXT_LOONGSON_2F:
19596 fputs ("ST Microelectronics Loongson 2F", stdout);
19597 break;
19598 case AFL_EXT_INTERAPTIV_MR2:
19599 fputs ("Imagination interAptiv MR2", stdout);
19600 break;
19601 default:
19602 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
19606 static signed int
19607 get_mips_reg_size (int reg_size)
19609 return (reg_size == AFL_REG_NONE) ? 0
19610 : (reg_size == AFL_REG_32) ? 32
19611 : (reg_size == AFL_REG_64) ? 64
19612 : (reg_size == AFL_REG_128) ? 128
19613 : -1;
19616 static bool
19617 process_mips_specific (Filedata * filedata)
19619 Elf_Internal_Dyn * entry;
19620 Elf_Internal_Shdr *sect = NULL;
19621 size_t liblist_offset = 0;
19622 size_t liblistno = 0;
19623 size_t conflictsno = 0;
19624 size_t options_offset = 0;
19625 size_t conflicts_offset = 0;
19626 size_t pltrelsz = 0;
19627 size_t pltrel = 0;
19628 uint64_t pltgot = 0;
19629 uint64_t mips_pltgot = 0;
19630 uint64_t jmprel = 0;
19631 uint64_t local_gotno = 0;
19632 uint64_t gotsym = 0;
19633 uint64_t symtabno = 0;
19634 bool res = true;
19636 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
19637 display_mips_gnu_attribute))
19638 res = false;
19640 sect = find_section (filedata, ".MIPS.abiflags");
19642 if (sect != NULL)
19644 Elf_External_ABIFlags_v0 *abiflags_ext;
19645 Elf_Internal_ABIFlags_v0 abiflags_in;
19647 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
19649 error (_("Corrupt MIPS ABI Flags section.\n"));
19650 res = false;
19652 else
19654 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
19655 sect->sh_size, _("MIPS ABI Flags section"));
19656 if (abiflags_ext)
19658 abiflags_in.version = BYTE_GET (abiflags_ext->version);
19659 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
19660 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
19661 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
19662 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
19663 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
19664 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
19665 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
19666 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
19667 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
19668 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
19670 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
19671 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
19672 if (abiflags_in.isa_rev > 1)
19673 printf ("r%d", abiflags_in.isa_rev);
19674 printf ("\nGPR size: %d",
19675 get_mips_reg_size (abiflags_in.gpr_size));
19676 printf ("\nCPR1 size: %d",
19677 get_mips_reg_size (abiflags_in.cpr1_size));
19678 printf ("\nCPR2 size: %d",
19679 get_mips_reg_size (abiflags_in.cpr2_size));
19680 fputs ("\nFP ABI: ", stdout);
19681 print_mips_fp_abi_value (abiflags_in.fp_abi);
19682 fputs ("ISA Extension: ", stdout);
19683 print_mips_isa_ext (abiflags_in.isa_ext);
19684 fputs ("\nASEs:", stdout);
19685 print_mips_ases (abiflags_in.ases);
19686 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
19687 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
19688 fputc ('\n', stdout);
19689 free (abiflags_ext);
19694 /* We have a lot of special sections. Thanks SGI! */
19695 if (filedata->dynamic_section == NULL)
19697 /* No dynamic information available. See if there is static GOT. */
19698 sect = find_section (filedata, ".got");
19699 if (sect != NULL)
19701 unsigned char *data_end;
19702 unsigned char *data;
19703 uint64_t ent, end;
19704 int addr_size;
19706 pltgot = sect->sh_addr;
19708 ent = pltgot;
19709 addr_size = (is_32bit_elf ? 4 : 8);
19710 end = pltgot + sect->sh_size;
19712 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
19713 end - pltgot, 1,
19714 _("Global Offset Table data"));
19715 /* PR 12855: Null data is handled gracefully throughout. */
19716 data_end = data + (end - pltgot);
19718 printf (_("\nStatic GOT:\n"));
19719 printf (_(" Canonical gp value: "));
19720 print_vma (ent + 0x7ff0, LONG_HEX);
19721 printf ("\n\n");
19723 /* In a dynamic binary GOT[0] is reserved for the dynamic
19724 loader to store the lazy resolver pointer, however in
19725 a static binary it may well have been omitted and GOT
19726 reduced to a table of addresses.
19727 PR 21344: Check for the entry being fully available
19728 before fetching it. */
19729 if (data
19730 && data + ent - pltgot + addr_size <= data_end
19731 && byte_get (data + ent - pltgot, addr_size) == 0)
19733 printf (_(" Reserved entries:\n"));
19734 printf (_(" %*s %10s %*s\n"),
19735 addr_size * 2, _("Address"), _("Access"),
19736 addr_size * 2, _("Value"));
19737 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19738 printf ("\n");
19739 if (ent == (uint64_t) -1)
19740 goto sgot_print_fail;
19742 /* Check for the MSB of GOT[1] being set, identifying a
19743 GNU object. This entry will be used by some runtime
19744 loaders, to store the module pointer. Otherwise this
19745 is an ordinary local entry.
19746 PR 21344: Check for the entry being fully available
19747 before fetching it. */
19748 if (data
19749 && data + ent - pltgot + addr_size <= data_end
19750 && (byte_get (data + ent - pltgot, addr_size)
19751 >> (addr_size * 8 - 1)) != 0)
19753 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19754 printf ("\n");
19755 if (ent == (uint64_t) -1)
19756 goto sgot_print_fail;
19758 printf ("\n");
19761 if (data != NULL && ent < end)
19763 printf (_(" Local entries:\n"));
19764 printf (" %*s %10s %*s\n",
19765 addr_size * 2, _("Address"), _("Access"),
19766 addr_size * 2, _("Value"));
19767 while (ent < end)
19769 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19770 printf ("\n");
19771 if (ent == (uint64_t) -1)
19772 goto sgot_print_fail;
19774 printf ("\n");
19777 sgot_print_fail:
19778 free (data);
19780 return res;
19783 for (entry = filedata->dynamic_section;
19784 /* PR 17531 file: 012-50589-0.004. */
19785 (entry < filedata->dynamic_section + filedata->dynamic_nent
19786 && entry->d_tag != DT_NULL);
19787 ++entry)
19788 switch (entry->d_tag)
19790 case DT_MIPS_LIBLIST:
19791 liblist_offset
19792 = offset_from_vma (filedata, entry->d_un.d_val,
19793 liblistno * sizeof (Elf32_External_Lib));
19794 break;
19795 case DT_MIPS_LIBLISTNO:
19796 liblistno = entry->d_un.d_val;
19797 break;
19798 case DT_MIPS_OPTIONS:
19799 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
19800 break;
19801 case DT_MIPS_CONFLICT:
19802 conflicts_offset
19803 = offset_from_vma (filedata, entry->d_un.d_val,
19804 conflictsno * sizeof (Elf32_External_Conflict));
19805 break;
19806 case DT_MIPS_CONFLICTNO:
19807 conflictsno = entry->d_un.d_val;
19808 break;
19809 case DT_PLTGOT:
19810 pltgot = entry->d_un.d_ptr;
19811 break;
19812 case DT_MIPS_LOCAL_GOTNO:
19813 local_gotno = entry->d_un.d_val;
19814 break;
19815 case DT_MIPS_GOTSYM:
19816 gotsym = entry->d_un.d_val;
19817 break;
19818 case DT_MIPS_SYMTABNO:
19819 symtabno = entry->d_un.d_val;
19820 break;
19821 case DT_MIPS_PLTGOT:
19822 mips_pltgot = entry->d_un.d_ptr;
19823 break;
19824 case DT_PLTREL:
19825 pltrel = entry->d_un.d_val;
19826 break;
19827 case DT_PLTRELSZ:
19828 pltrelsz = entry->d_un.d_val;
19829 break;
19830 case DT_JMPREL:
19831 jmprel = entry->d_un.d_ptr;
19832 break;
19833 default:
19834 break;
19837 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
19839 Elf32_External_Lib * elib;
19840 size_t cnt;
19842 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
19843 sizeof (Elf32_External_Lib),
19844 liblistno,
19845 _("liblist section data"));
19846 if (elib)
19848 printf (ngettext ("\nSection '.liblist' contains %zu entry:\n",
19849 "\nSection '.liblist' contains %zu entries:\n",
19850 liblistno),
19851 liblistno);
19852 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
19853 stdout);
19855 for (cnt = 0; cnt < liblistno; ++cnt)
19857 Elf32_Lib liblist;
19858 time_t atime;
19859 char timebuf[128];
19860 struct tm * tmp;
19862 liblist.l_name = BYTE_GET (elib[cnt].l_name);
19863 atime = BYTE_GET (elib[cnt].l_time_stamp);
19864 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19865 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19866 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19868 tmp = gmtime (&atime);
19869 snprintf (timebuf, sizeof (timebuf),
19870 "%04u-%02u-%02uT%02u:%02u:%02u",
19871 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19872 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
19874 printf ("%3zu: ", cnt);
19875 if (valid_dynamic_name (filedata, liblist.l_name))
19876 print_symbol_name (20, get_dynamic_name (filedata, liblist.l_name));
19877 else
19878 printf (_("<corrupt: %9ld>"), liblist.l_name);
19879 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
19880 liblist.l_version);
19882 if (liblist.l_flags == 0)
19883 puts (_(" NONE"));
19884 else
19886 static const struct
19888 const char * name;
19889 int bit;
19891 l_flags_vals[] =
19893 { " EXACT_MATCH", LL_EXACT_MATCH },
19894 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
19895 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
19896 { " EXPORTS", LL_EXPORTS },
19897 { " DELAY_LOAD", LL_DELAY_LOAD },
19898 { " DELTA", LL_DELTA }
19900 int flags = liblist.l_flags;
19901 size_t fcnt;
19903 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
19904 if ((flags & l_flags_vals[fcnt].bit) != 0)
19906 fputs (l_flags_vals[fcnt].name, stdout);
19907 flags ^= l_flags_vals[fcnt].bit;
19909 if (flags != 0)
19910 printf (" %#x", (unsigned int) flags);
19912 puts ("");
19916 free (elib);
19918 else
19919 res = false;
19922 if (options_offset != 0)
19924 Elf_External_Options * eopt;
19925 size_t offset;
19926 int cnt;
19928 /* Find the section header so that we get the size. */
19929 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
19930 /* PR 17533 file: 012-277276-0.004. */
19931 if (sect == NULL)
19933 error (_("No MIPS_OPTIONS header found\n"));
19934 return false;
19936 /* PR 24243 */
19937 if (sect->sh_size < sizeof (* eopt))
19939 error (_("The MIPS options section is too small.\n"));
19940 return false;
19943 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
19944 sect->sh_size, _("options"));
19945 if (eopt)
19947 Elf_Internal_Options option;
19949 offset = cnt = 0;
19950 while (offset <= sect->sh_size - sizeof (* eopt))
19952 Elf_External_Options * eoption;
19953 unsigned int optsize;
19955 eoption = (Elf_External_Options *) ((char *) eopt + offset);
19957 optsize = BYTE_GET (eoption->size);
19959 /* PR 17531: file: ffa0fa3b. */
19960 if (optsize < sizeof (* eopt)
19961 || optsize > sect->sh_size - offset)
19963 error (_("Invalid size (%u) for MIPS option\n"),
19964 optsize);
19965 free (eopt);
19966 return false;
19968 offset += optsize;
19969 ++cnt;
19972 printf (ngettext ("\nSection '%s' contains %d entry:\n",
19973 "\nSection '%s' contains %d entries:\n",
19974 cnt),
19975 printable_section_name (filedata, sect), cnt);
19977 offset = 0;
19978 while (cnt-- > 0)
19980 size_t len;
19981 Elf_External_Options * eoption;
19983 eoption = (Elf_External_Options *) ((char *) eopt + offset);
19985 option.kind = BYTE_GET (eoption->kind);
19986 option.size = BYTE_GET (eoption->size);
19987 option.section = BYTE_GET (eoption->section);
19988 option.info = BYTE_GET (eoption->info);
19990 switch (option.kind)
19992 case ODK_NULL:
19993 /* This shouldn't happen. */
19994 printf (" NULL %" PRId16 " %" PRIx32,
19995 option.section, option.info);
19996 break;
19998 case ODK_REGINFO:
19999 printf (" REGINFO ");
20000 if (filedata->file_header.e_machine == EM_MIPS)
20002 Elf32_External_RegInfo * ereg;
20003 Elf32_RegInfo reginfo;
20005 /* 32bit form. */
20006 if (option.size < (sizeof (Elf_External_Options)
20007 + sizeof (Elf32_External_RegInfo)))
20009 printf (_("<corrupt>\n"));
20010 error (_("Truncated MIPS REGINFO option\n"));
20011 cnt = 0;
20012 break;
20015 ereg = (Elf32_External_RegInfo *) (eoption + 1);
20017 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
20018 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
20019 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
20020 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
20021 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
20022 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
20024 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
20025 reginfo.ri_gprmask, reginfo.ri_gp_value);
20026 printf (" "
20027 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
20028 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
20029 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
20030 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
20032 else
20034 /* 64 bit form. */
20035 Elf64_External_RegInfo * ereg;
20036 Elf64_Internal_RegInfo reginfo;
20038 if (option.size < (sizeof (Elf_External_Options)
20039 + sizeof (Elf64_External_RegInfo)))
20041 printf (_("<corrupt>\n"));
20042 error (_("Truncated MIPS REGINFO option\n"));
20043 cnt = 0;
20044 break;
20047 ereg = (Elf64_External_RegInfo *) (eoption + 1);
20048 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
20049 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
20050 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
20051 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
20052 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
20053 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
20055 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
20056 reginfo.ri_gprmask, reginfo.ri_gp_value);
20057 printf (" "
20058 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
20059 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
20060 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
20061 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
20063 offset += option.size;
20064 continue;
20066 case ODK_EXCEPTIONS:
20067 fputs (" EXCEPTIONS fpe_min(", stdout);
20068 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
20069 fputs (") fpe_max(", stdout);
20070 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
20071 fputs (")", stdout);
20073 if (option.info & OEX_PAGE0)
20074 fputs (" PAGE0", stdout);
20075 if (option.info & OEX_SMM)
20076 fputs (" SMM", stdout);
20077 if (option.info & OEX_FPDBUG)
20078 fputs (" FPDBUG", stdout);
20079 if (option.info & OEX_DISMISS)
20080 fputs (" DISMISS", stdout);
20081 break;
20083 case ODK_PAD:
20084 fputs (" PAD ", stdout);
20085 if (option.info & OPAD_PREFIX)
20086 fputs (" PREFIX", stdout);
20087 if (option.info & OPAD_POSTFIX)
20088 fputs (" POSTFIX", stdout);
20089 if (option.info & OPAD_SYMBOL)
20090 fputs (" SYMBOL", stdout);
20091 break;
20093 case ODK_HWPATCH:
20094 fputs (" HWPATCH ", stdout);
20095 if (option.info & OHW_R4KEOP)
20096 fputs (" R4KEOP", stdout);
20097 if (option.info & OHW_R8KPFETCH)
20098 fputs (" R8KPFETCH", stdout);
20099 if (option.info & OHW_R5KEOP)
20100 fputs (" R5KEOP", stdout);
20101 if (option.info & OHW_R5KCVTL)
20102 fputs (" R5KCVTL", stdout);
20103 break;
20105 case ODK_FILL:
20106 fputs (" FILL ", stdout);
20107 /* XXX Print content of info word? */
20108 break;
20110 case ODK_TAGS:
20111 fputs (" TAGS ", stdout);
20112 /* XXX Print content of info word? */
20113 break;
20115 case ODK_HWAND:
20116 fputs (" HWAND ", stdout);
20117 if (option.info & OHWA0_R4KEOP_CHECKED)
20118 fputs (" R4KEOP_CHECKED", stdout);
20119 if (option.info & OHWA0_R4KEOP_CLEAN)
20120 fputs (" R4KEOP_CLEAN", stdout);
20121 break;
20123 case ODK_HWOR:
20124 fputs (" HWOR ", stdout);
20125 if (option.info & OHWA0_R4KEOP_CHECKED)
20126 fputs (" R4KEOP_CHECKED", stdout);
20127 if (option.info & OHWA0_R4KEOP_CLEAN)
20128 fputs (" R4KEOP_CLEAN", stdout);
20129 break;
20131 case ODK_GP_GROUP:
20132 printf (" GP_GROUP %#06x self-contained %#06x",
20133 option.info & OGP_GROUP,
20134 (option.info & OGP_SELF) >> 16);
20135 break;
20137 case ODK_IDENT:
20138 printf (" IDENT %#06x self-contained %#06x",
20139 option.info & OGP_GROUP,
20140 (option.info & OGP_SELF) >> 16);
20141 break;
20143 default:
20144 /* This shouldn't happen. */
20145 printf (" %3d ??? %" PRId16 " %" PRIx32,
20146 option.kind, option.section, option.info);
20147 break;
20150 len = sizeof (* eopt);
20151 while (len < option.size)
20153 unsigned char datum = *((unsigned char *) eoption + len);
20155 if (ISPRINT (datum))
20156 printf ("%c", datum);
20157 else
20158 printf ("\\%03o", datum);
20159 len ++;
20161 fputs ("\n", stdout);
20163 offset += option.size;
20165 free (eopt);
20167 else
20168 res = false;
20171 if (conflicts_offset != 0 && conflictsno != 0)
20173 Elf32_Conflict * iconf;
20174 size_t cnt;
20176 if (filedata->dynamic_symbols == NULL)
20178 error (_("conflict list found without a dynamic symbol table\n"));
20179 return false;
20182 /* PR 21345 - print a slightly more helpful error message
20183 if we are sure that the cmalloc will fail. */
20184 if (conflictsno > filedata->file_size / sizeof (* iconf))
20186 error (_("Overlarge number of conflicts detected: %zx\n"),
20187 conflictsno);
20188 return false;
20191 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
20192 if (iconf == NULL)
20194 error (_("Out of memory allocating space for dynamic conflicts\n"));
20195 return false;
20198 if (is_32bit_elf)
20200 Elf32_External_Conflict * econf32;
20202 econf32 = (Elf32_External_Conflict *)
20203 get_data (NULL, filedata, conflicts_offset,
20204 sizeof (*econf32), conflictsno, _("conflict"));
20205 if (!econf32)
20207 free (iconf);
20208 return false;
20211 for (cnt = 0; cnt < conflictsno; ++cnt)
20212 iconf[cnt] = BYTE_GET (econf32[cnt]);
20214 free (econf32);
20216 else
20218 Elf64_External_Conflict * econf64;
20220 econf64 = (Elf64_External_Conflict *)
20221 get_data (NULL, filedata, conflicts_offset,
20222 sizeof (*econf64), conflictsno, _("conflict"));
20223 if (!econf64)
20225 free (iconf);
20226 return false;
20229 for (cnt = 0; cnt < conflictsno; ++cnt)
20230 iconf[cnt] = BYTE_GET (econf64[cnt]);
20232 free (econf64);
20235 printf (ngettext ("\nSection '.conflict' contains %zu entry:\n",
20236 "\nSection '.conflict' contains %zu entries:\n",
20237 conflictsno),
20238 conflictsno);
20239 puts (_(" Num: Index Value Name"));
20241 for (cnt = 0; cnt < conflictsno; ++cnt)
20243 printf ("%5zu: %8lu ", cnt, iconf[cnt]);
20245 if (iconf[cnt] >= filedata->num_dynamic_syms)
20246 printf (_("<corrupt symbol index>"));
20247 else
20249 Elf_Internal_Sym * psym;
20251 psym = & filedata->dynamic_symbols[iconf[cnt]];
20252 print_vma (psym->st_value, FULL_HEX);
20253 putchar (' ');
20254 if (valid_dynamic_name (filedata, psym->st_name))
20255 print_symbol_name (25, get_dynamic_name (filedata, psym->st_name));
20256 else
20257 printf (_("<corrupt: %14ld>"), psym->st_name);
20259 putchar ('\n');
20262 free (iconf);
20265 if (pltgot != 0 && local_gotno != 0)
20267 uint64_t ent, local_end, global_end;
20268 size_t i, offset;
20269 unsigned char * data;
20270 unsigned char * data_end;
20271 int addr_size;
20273 ent = pltgot;
20274 addr_size = (is_32bit_elf ? 4 : 8);
20275 local_end = pltgot + local_gotno * addr_size;
20277 /* PR binutils/17533 file: 012-111227-0.004 */
20278 if (symtabno < gotsym)
20280 error (_("The GOT symbol offset (%" PRIu64
20281 ") is greater than the symbol table size (%" PRIu64 ")\n"),
20282 gotsym, symtabno);
20283 return false;
20286 global_end = local_end + (symtabno - gotsym) * addr_size;
20287 /* PR 17531: file: 54c91a34. */
20288 if (global_end < local_end)
20290 error (_("Too many GOT symbols: %" PRIu64 "\n"), symtabno);
20291 return false;
20294 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
20295 data = (unsigned char *) get_data (NULL, filedata, offset,
20296 global_end - pltgot, 1,
20297 _("Global Offset Table data"));
20298 /* PR 12855: Null data is handled gracefully throughout. */
20299 data_end = data + (global_end - pltgot);
20301 printf (_("\nPrimary GOT:\n"));
20302 printf (_(" Canonical gp value: "));
20303 print_vma (pltgot + 0x7ff0, LONG_HEX);
20304 printf ("\n\n");
20306 printf (_(" Reserved entries:\n"));
20307 printf (_(" %*s %10s %*s Purpose\n"),
20308 addr_size * 2, _("Address"), _("Access"),
20309 addr_size * 2, _("Initial"));
20310 ent = print_mips_got_entry (data, pltgot, ent, data_end);
20311 printf (_(" Lazy resolver\n"));
20312 if (ent == (uint64_t) -1)
20313 goto got_print_fail;
20315 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
20316 This entry will be used by some runtime loaders, to store the
20317 module pointer. Otherwise this is an ordinary local entry.
20318 PR 21344: Check for the entry being fully available before
20319 fetching it. */
20320 if (data
20321 && data + ent - pltgot + addr_size <= data_end
20322 && (byte_get (data + ent - pltgot, addr_size)
20323 >> (addr_size * 8 - 1)) != 0)
20325 ent = print_mips_got_entry (data, pltgot, ent, data_end);
20326 printf (_(" Module pointer (GNU extension)\n"));
20327 if (ent == (uint64_t) -1)
20328 goto got_print_fail;
20330 printf ("\n");
20332 if (data != NULL && ent < local_end)
20334 printf (_(" Local entries:\n"));
20335 printf (" %*s %10s %*s\n",
20336 addr_size * 2, _("Address"), _("Access"),
20337 addr_size * 2, _("Initial"));
20338 while (ent < local_end)
20340 ent = print_mips_got_entry (data, pltgot, ent, data_end);
20341 printf ("\n");
20342 if (ent == (uint64_t) -1)
20343 goto got_print_fail;
20345 printf ("\n");
20348 if (data != NULL && gotsym < symtabno)
20350 int sym_width;
20352 printf (_(" Global entries:\n"));
20353 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
20354 addr_size * 2, _("Address"),
20355 _("Access"),
20356 addr_size * 2, _("Initial"),
20357 addr_size * 2, _("Sym.Val."),
20358 _("Type"),
20359 /* Note for translators: "Ndx" = abbreviated form of "Index". */
20360 _("Ndx"), _("Name"));
20362 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
20364 for (i = gotsym; i < symtabno; i++)
20366 ent = print_mips_got_entry (data, pltgot, ent, data_end);
20367 printf (" ");
20369 if (filedata->dynamic_symbols == NULL)
20370 printf (_("<no dynamic symbols>"));
20371 else if (i < filedata->num_dynamic_syms)
20373 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
20375 print_vma (psym->st_value, LONG_HEX);
20376 printf (" %-7s ", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
20378 bool is_special;
20379 const char * s = printable_section_name_from_index (filedata, psym->st_shndx, & is_special);
20380 if (is_special)
20381 printf ("%3s ", s);
20382 else
20383 printf ("%3u ", psym->st_shndx);
20385 if (valid_dynamic_name (filedata, psym->st_name))
20386 print_symbol_name (sym_width,
20387 get_dynamic_name (filedata, psym->st_name));
20388 else
20389 printf (_("<corrupt: %14ld>"), psym->st_name);
20391 else
20392 printf (_("<symbol index %zu exceeds number of dynamic symbols>"),
20395 printf ("\n");
20396 if (ent == (uint64_t) -1)
20397 break;
20399 printf ("\n");
20402 got_print_fail:
20403 free (data);
20406 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
20408 uint64_t ent, end;
20409 uint64_t offset, rel_offset;
20410 uint64_t count, i;
20411 unsigned char * data;
20412 int addr_size, sym_width;
20413 Elf_Internal_Rela * rels;
20415 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
20416 if (pltrel == DT_RELA)
20418 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
20419 return false;
20421 else
20423 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
20424 return false;
20427 ent = mips_pltgot;
20428 addr_size = (is_32bit_elf ? 4 : 8);
20429 end = mips_pltgot + (2 + count) * addr_size;
20431 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
20432 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
20433 1, _("Procedure Linkage Table data"));
20434 if (data == NULL)
20436 free (rels);
20437 return false;
20440 printf ("\nPLT GOT:\n\n");
20441 printf (_(" Reserved entries:\n"));
20442 printf (_(" %*s %*s Purpose\n"),
20443 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
20444 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
20445 printf (_(" PLT lazy resolver\n"));
20446 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
20447 printf (_(" Module pointer\n"));
20448 printf ("\n");
20450 printf (_(" Entries:\n"));
20451 printf (" %*s %*s %*s %-7s %3s %s\n",
20452 addr_size * 2, _("Address"),
20453 addr_size * 2, _("Initial"),
20454 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
20455 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
20456 for (i = 0; i < count; i++)
20458 uint64_t idx = get_reloc_symindex (rels[i].r_info);
20460 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
20461 printf (" ");
20463 if (idx >= filedata->num_dynamic_syms)
20464 printf (_("<corrupt symbol index: %" PRIu64 ">"), idx);
20465 else
20467 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
20469 print_vma (psym->st_value, LONG_HEX);
20470 printf (" %-7s %3s ",
20471 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
20472 printable_section_name_from_index (filedata, psym->st_shndx, NULL));
20473 if (valid_dynamic_name (filedata, psym->st_name))
20474 print_symbol_name (sym_width,
20475 get_dynamic_name (filedata, psym->st_name));
20476 else
20477 printf (_("<corrupt: %14ld>"), psym->st_name);
20479 printf ("\n");
20481 printf ("\n");
20483 free (data);
20484 free (rels);
20487 return res;
20490 static bool
20491 process_nds32_specific (Filedata * filedata)
20493 Elf_Internal_Shdr *sect = NULL;
20495 sect = find_section (filedata, ".nds32_e_flags");
20496 if (sect != NULL && sect->sh_size >= 4)
20498 unsigned char *buf;
20499 unsigned int flag;
20501 printf ("\nNDS32 elf flags section:\n");
20502 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
20503 _("NDS32 elf flags section"));
20505 if (buf == NULL)
20506 return false;
20508 flag = byte_get (buf, 4);
20509 free (buf);
20510 switch (flag & 0x3)
20512 case 0:
20513 printf ("(VEC_SIZE):\tNo entry.\n");
20514 break;
20515 case 1:
20516 printf ("(VEC_SIZE):\t4 bytes\n");
20517 break;
20518 case 2:
20519 printf ("(VEC_SIZE):\t16 bytes\n");
20520 break;
20521 case 3:
20522 printf ("(VEC_SIZE):\treserved\n");
20523 break;
20527 return true;
20530 static bool
20531 process_gnu_liblist (Filedata * filedata)
20533 Elf_Internal_Shdr * section;
20534 Elf_Internal_Shdr * string_sec;
20535 Elf32_External_Lib * elib;
20536 char * strtab;
20537 size_t strtab_size;
20538 size_t cnt;
20539 uint64_t num_liblist;
20540 unsigned i;
20541 bool res = true;
20543 if (! do_arch)
20544 return true;
20546 for (i = 0, section = filedata->section_headers;
20547 i < filedata->file_header.e_shnum;
20548 i++, section++)
20550 switch (section->sh_type)
20552 case SHT_GNU_LIBLIST:
20553 if (section->sh_link >= filedata->file_header.e_shnum)
20554 break;
20556 elib = (Elf32_External_Lib *)
20557 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
20558 _("liblist section data"));
20560 if (elib == NULL)
20562 res = false;
20563 break;
20566 string_sec = filedata->section_headers + section->sh_link;
20567 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
20568 string_sec->sh_size,
20569 _("liblist string table"));
20570 if (strtab == NULL
20571 || section->sh_entsize != sizeof (Elf32_External_Lib))
20573 free (elib);
20574 free (strtab);
20575 res = false;
20576 break;
20578 strtab_size = string_sec->sh_size;
20580 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
20581 printf (ngettext ("\nLibrary list section '%s' contains %" PRIu64
20582 " entries:\n",
20583 "\nLibrary list section '%s' contains %" PRIu64
20584 " entries:\n",
20585 num_liblist),
20586 printable_section_name (filedata, section),
20587 num_liblist);
20589 puts (_(" Library Time Stamp Checksum Version Flags"));
20591 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
20592 ++cnt)
20594 Elf32_Lib liblist;
20595 time_t atime;
20596 char timebuf[128];
20597 struct tm * tmp;
20599 liblist.l_name = BYTE_GET (elib[cnt].l_name);
20600 atime = BYTE_GET (elib[cnt].l_time_stamp);
20601 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
20602 liblist.l_version = BYTE_GET (elib[cnt].l_version);
20603 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
20605 tmp = gmtime (&atime);
20606 snprintf (timebuf, sizeof (timebuf),
20607 "%04u-%02u-%02uT%02u:%02u:%02u",
20608 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
20609 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
20611 printf ("%3zu: ", cnt);
20612 if (do_wide)
20613 printf ("%-20s", liblist.l_name < strtab_size
20614 ? strtab + liblist.l_name : _("<corrupt>"));
20615 else
20616 printf ("%-20.20s", liblist.l_name < strtab_size
20617 ? strtab + liblist.l_name : _("<corrupt>"));
20618 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
20619 liblist.l_version, liblist.l_flags);
20622 free (elib);
20623 free (strtab);
20627 return res;
20630 static const char *
20631 get_note_type (Filedata * filedata, unsigned e_type)
20633 static char buff[64];
20635 if (filedata->file_header.e_type == ET_CORE)
20636 switch (e_type)
20638 case NT_AUXV:
20639 return _("NT_AUXV (auxiliary vector)");
20640 case NT_PRSTATUS:
20641 return _("NT_PRSTATUS (prstatus structure)");
20642 case NT_FPREGSET:
20643 return _("NT_FPREGSET (floating point registers)");
20644 case NT_PRPSINFO:
20645 return _("NT_PRPSINFO (prpsinfo structure)");
20646 case NT_TASKSTRUCT:
20647 return _("NT_TASKSTRUCT (task structure)");
20648 case NT_GDB_TDESC:
20649 return _("NT_GDB_TDESC (GDB XML target description)");
20650 case NT_PRXFPREG:
20651 return _("NT_PRXFPREG (user_xfpregs structure)");
20652 case NT_PPC_VMX:
20653 return _("NT_PPC_VMX (ppc Altivec registers)");
20654 case NT_PPC_VSX:
20655 return _("NT_PPC_VSX (ppc VSX registers)");
20656 case NT_PPC_TAR:
20657 return _("NT_PPC_TAR (ppc TAR register)");
20658 case NT_PPC_PPR:
20659 return _("NT_PPC_PPR (ppc PPR register)");
20660 case NT_PPC_DSCR:
20661 return _("NT_PPC_DSCR (ppc DSCR register)");
20662 case NT_PPC_EBB:
20663 return _("NT_PPC_EBB (ppc EBB registers)");
20664 case NT_PPC_PMU:
20665 return _("NT_PPC_PMU (ppc PMU registers)");
20666 case NT_PPC_TM_CGPR:
20667 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
20668 case NT_PPC_TM_CFPR:
20669 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
20670 case NT_PPC_TM_CVMX:
20671 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
20672 case NT_PPC_TM_CVSX:
20673 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
20674 case NT_PPC_TM_SPR:
20675 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
20676 case NT_PPC_TM_CTAR:
20677 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
20678 case NT_PPC_TM_CPPR:
20679 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
20680 case NT_PPC_TM_CDSCR:
20681 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
20682 case NT_386_TLS:
20683 return _("NT_386_TLS (x86 TLS information)");
20684 case NT_386_IOPERM:
20685 return _("NT_386_IOPERM (x86 I/O permissions)");
20686 case NT_X86_XSTATE:
20687 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
20688 case NT_X86_CET:
20689 return _("NT_X86_CET (x86 CET state)");
20690 case NT_X86_SHSTK:
20691 return _("NT_X86_SHSTK (x86 SHSTK state)");
20692 case NT_S390_HIGH_GPRS:
20693 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
20694 case NT_S390_TIMER:
20695 return _("NT_S390_TIMER (s390 timer register)");
20696 case NT_S390_TODCMP:
20697 return _("NT_S390_TODCMP (s390 TOD comparator register)");
20698 case NT_S390_TODPREG:
20699 return _("NT_S390_TODPREG (s390 TOD programmable register)");
20700 case NT_S390_CTRS:
20701 return _("NT_S390_CTRS (s390 control registers)");
20702 case NT_S390_PREFIX:
20703 return _("NT_S390_PREFIX (s390 prefix register)");
20704 case NT_S390_LAST_BREAK:
20705 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
20706 case NT_S390_SYSTEM_CALL:
20707 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
20708 case NT_S390_TDB:
20709 return _("NT_S390_TDB (s390 transaction diagnostic block)");
20710 case NT_S390_VXRS_LOW:
20711 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
20712 case NT_S390_VXRS_HIGH:
20713 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
20714 case NT_S390_GS_CB:
20715 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
20716 case NT_S390_GS_BC:
20717 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
20718 case NT_ARM_VFP:
20719 return _("NT_ARM_VFP (arm VFP registers)");
20720 case NT_ARM_TLS:
20721 return _("NT_ARM_TLS (AArch TLS registers)");
20722 case NT_ARM_HW_BREAK:
20723 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
20724 case NT_ARM_HW_WATCH:
20725 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
20726 case NT_ARM_SYSTEM_CALL:
20727 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
20728 case NT_ARM_SVE:
20729 return _("NT_ARM_SVE (AArch SVE registers)");
20730 case NT_ARM_PAC_MASK:
20731 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
20732 case NT_ARM_PACA_KEYS:
20733 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
20734 case NT_ARM_PACG_KEYS:
20735 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
20736 case NT_ARM_TAGGED_ADDR_CTRL:
20737 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
20738 case NT_ARM_SSVE:
20739 return _("NT_ARM_SSVE (AArch64 streaming SVE registers)");
20740 case NT_ARM_ZA:
20741 return _("NT_ARM_ZA (AArch64 SME ZA register)");
20742 case NT_ARM_ZT:
20743 return _("NT_ARM_ZT (AArch64 SME2 ZT registers)");
20744 case NT_ARM_PAC_ENABLED_KEYS:
20745 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
20746 case NT_ARC_V2:
20747 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
20748 case NT_RISCV_CSR:
20749 return _("NT_RISCV_CSR (RISC-V control and status registers)");
20750 case NT_PSTATUS:
20751 return _("NT_PSTATUS (pstatus structure)");
20752 case NT_FPREGS:
20753 return _("NT_FPREGS (floating point registers)");
20754 case NT_PSINFO:
20755 return _("NT_PSINFO (psinfo structure)");
20756 case NT_LWPSTATUS:
20757 return _("NT_LWPSTATUS (lwpstatus_t structure)");
20758 case NT_LWPSINFO:
20759 return _("NT_LWPSINFO (lwpsinfo_t structure)");
20760 case NT_WIN32PSTATUS:
20761 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
20762 case NT_SIGINFO:
20763 return _("NT_SIGINFO (siginfo_t data)");
20764 case NT_FILE:
20765 return _("NT_FILE (mapped files)");
20766 default:
20767 break;
20769 else
20770 switch (e_type)
20772 case NT_VERSION:
20773 return _("NT_VERSION (version)");
20774 case NT_ARCH:
20775 return _("NT_ARCH (architecture)");
20776 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
20777 return _("OPEN");
20778 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
20779 return _("func");
20780 case NT_GO_BUILDID:
20781 return _("GO BUILDID");
20782 case FDO_PACKAGING_METADATA:
20783 return _("FDO_PACKAGING_METADATA");
20784 case FDO_DLOPEN_METADATA:
20785 return _("FDO_DLOPEN_METADATA");
20786 default:
20787 break;
20790 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20791 return buff;
20794 static bool
20795 print_core_note (Elf_Internal_Note *pnote)
20797 unsigned int addr_size = is_32bit_elf ? 4 : 8;
20798 uint64_t count, page_size;
20799 unsigned char *descdata, *filenames, *descend;
20801 if (pnote->type != NT_FILE)
20803 if (do_wide)
20804 printf ("\n");
20805 return true;
20808 if (pnote->descsz < 2 * addr_size)
20810 error (_(" Malformed note - too short for header\n"));
20811 return false;
20814 descdata = (unsigned char *) pnote->descdata;
20815 descend = descdata + pnote->descsz;
20817 if (descdata[pnote->descsz - 1] != '\0')
20819 error (_(" Malformed note - does not end with \\0\n"));
20820 return false;
20823 count = byte_get (descdata, addr_size);
20824 descdata += addr_size;
20826 page_size = byte_get (descdata, addr_size);
20827 descdata += addr_size;
20829 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
20830 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
20832 error (_(" Malformed note - too short for supplied file count\n"));
20833 return false;
20836 printf (_(" Page size: "));
20837 print_vma (page_size, DEC);
20838 printf ("\n");
20840 printf (_(" %*s%*s%*s\n"),
20841 (int) (2 + 2 * addr_size), _("Start"),
20842 (int) (4 + 2 * addr_size), _("End"),
20843 (int) (4 + 2 * addr_size), _("Page Offset"));
20844 filenames = descdata + count * 3 * addr_size;
20845 while (count-- > 0)
20847 uint64_t start, end, file_ofs;
20849 if (filenames == descend)
20851 error (_(" Malformed note - filenames end too early\n"));
20852 return false;
20855 start = byte_get (descdata, addr_size);
20856 descdata += addr_size;
20857 end = byte_get (descdata, addr_size);
20858 descdata += addr_size;
20859 file_ofs = byte_get (descdata, addr_size);
20860 descdata += addr_size;
20862 printf (" ");
20863 print_vma (start, FULL_HEX);
20864 printf (" ");
20865 print_vma (end, FULL_HEX);
20866 printf (" ");
20867 print_vma (file_ofs, FULL_HEX);
20868 printf ("\n %s\n", filenames);
20870 filenames += 1 + strlen ((char *) filenames);
20873 return true;
20876 static const char *
20877 get_gnu_elf_note_type (unsigned e_type)
20879 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
20880 switch (e_type)
20882 case NT_GNU_ABI_TAG:
20883 return _("NT_GNU_ABI_TAG (ABI version tag)");
20884 case NT_GNU_HWCAP:
20885 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
20886 case NT_GNU_BUILD_ID:
20887 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
20888 case NT_GNU_GOLD_VERSION:
20889 return _("NT_GNU_GOLD_VERSION (gold version)");
20890 case NT_GNU_PROPERTY_TYPE_0:
20891 return _("NT_GNU_PROPERTY_TYPE_0");
20892 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
20893 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
20894 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
20895 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
20896 default:
20898 static char buff[64];
20900 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20901 return buff;
20906 static void
20907 decode_x86_compat_isa (unsigned int bitmask)
20909 while (bitmask)
20911 unsigned int bit = bitmask & (- bitmask);
20913 bitmask &= ~ bit;
20914 switch (bit)
20916 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
20917 printf ("i486");
20918 break;
20919 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
20920 printf ("586");
20921 break;
20922 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
20923 printf ("686");
20924 break;
20925 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
20926 printf ("SSE");
20927 break;
20928 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
20929 printf ("SSE2");
20930 break;
20931 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
20932 printf ("SSE3");
20933 break;
20934 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
20935 printf ("SSSE3");
20936 break;
20937 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
20938 printf ("SSE4_1");
20939 break;
20940 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
20941 printf ("SSE4_2");
20942 break;
20943 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
20944 printf ("AVX");
20945 break;
20946 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
20947 printf ("AVX2");
20948 break;
20949 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
20950 printf ("AVX512F");
20951 break;
20952 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
20953 printf ("AVX512CD");
20954 break;
20955 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
20956 printf ("AVX512ER");
20957 break;
20958 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
20959 printf ("AVX512PF");
20960 break;
20961 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
20962 printf ("AVX512VL");
20963 break;
20964 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
20965 printf ("AVX512DQ");
20966 break;
20967 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
20968 printf ("AVX512BW");
20969 break;
20970 default:
20971 printf (_("<unknown: %x>"), bit);
20972 break;
20974 if (bitmask)
20975 printf (", ");
20979 static void
20980 decode_x86_compat_2_isa (unsigned int bitmask)
20982 if (!bitmask)
20984 printf (_("<None>"));
20985 return;
20988 while (bitmask)
20990 unsigned int bit = bitmask & (- bitmask);
20992 bitmask &= ~ bit;
20993 switch (bit)
20995 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
20996 printf ("CMOV");
20997 break;
20998 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
20999 printf ("SSE");
21000 break;
21001 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
21002 printf ("SSE2");
21003 break;
21004 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
21005 printf ("SSE3");
21006 break;
21007 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
21008 printf ("SSSE3");
21009 break;
21010 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
21011 printf ("SSE4_1");
21012 break;
21013 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
21014 printf ("SSE4_2");
21015 break;
21016 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
21017 printf ("AVX");
21018 break;
21019 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
21020 printf ("AVX2");
21021 break;
21022 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
21023 printf ("FMA");
21024 break;
21025 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
21026 printf ("AVX512F");
21027 break;
21028 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
21029 printf ("AVX512CD");
21030 break;
21031 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
21032 printf ("AVX512ER");
21033 break;
21034 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
21035 printf ("AVX512PF");
21036 break;
21037 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
21038 printf ("AVX512VL");
21039 break;
21040 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
21041 printf ("AVX512DQ");
21042 break;
21043 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
21044 printf ("AVX512BW");
21045 break;
21046 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
21047 printf ("AVX512_4FMAPS");
21048 break;
21049 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
21050 printf ("AVX512_4VNNIW");
21051 break;
21052 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
21053 printf ("AVX512_BITALG");
21054 break;
21055 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
21056 printf ("AVX512_IFMA");
21057 break;
21058 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
21059 printf ("AVX512_VBMI");
21060 break;
21061 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
21062 printf ("AVX512_VBMI2");
21063 break;
21064 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
21065 printf ("AVX512_VNNI");
21066 break;
21067 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
21068 printf ("AVX512_BF16");
21069 break;
21070 default:
21071 printf (_("<unknown: %x>"), bit);
21072 break;
21074 if (bitmask)
21075 printf (", ");
21079 static const char *
21080 get_amdgpu_elf_note_type (unsigned int e_type)
21082 switch (e_type)
21084 case NT_AMDGPU_METADATA:
21085 return _("NT_AMDGPU_METADATA (code object metadata)");
21086 default:
21088 static char buf[64];
21089 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
21090 return buf;
21095 static void
21096 decode_x86_isa (unsigned int bitmask)
21098 while (bitmask)
21100 unsigned int bit = bitmask & (- bitmask);
21102 bitmask &= ~ bit;
21103 switch (bit)
21105 case GNU_PROPERTY_X86_ISA_1_BASELINE:
21106 printf ("x86-64-baseline");
21107 break;
21108 case GNU_PROPERTY_X86_ISA_1_V2:
21109 printf ("x86-64-v2");
21110 break;
21111 case GNU_PROPERTY_X86_ISA_1_V3:
21112 printf ("x86-64-v3");
21113 break;
21114 case GNU_PROPERTY_X86_ISA_1_V4:
21115 printf ("x86-64-v4");
21116 break;
21117 default:
21118 printf (_("<unknown: %x>"), bit);
21119 break;
21121 if (bitmask)
21122 printf (", ");
21126 static void
21127 decode_x86_feature_1 (unsigned int bitmask)
21129 if (!bitmask)
21131 printf (_("<None>"));
21132 return;
21135 while (bitmask)
21137 unsigned int bit = bitmask & (- bitmask);
21139 bitmask &= ~ bit;
21140 switch (bit)
21142 case GNU_PROPERTY_X86_FEATURE_1_IBT:
21143 printf ("IBT");
21144 break;
21145 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
21146 printf ("SHSTK");
21147 break;
21148 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
21149 printf ("LAM_U48");
21150 break;
21151 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
21152 printf ("LAM_U57");
21153 break;
21154 default:
21155 printf (_("<unknown: %x>"), bit);
21156 break;
21158 if (bitmask)
21159 printf (", ");
21163 static void
21164 decode_x86_feature_2 (unsigned int bitmask)
21166 if (!bitmask)
21168 printf (_("<None>"));
21169 return;
21172 while (bitmask)
21174 unsigned int bit = bitmask & (- bitmask);
21176 bitmask &= ~ bit;
21177 switch (bit)
21179 case GNU_PROPERTY_X86_FEATURE_2_X86:
21180 printf ("x86");
21181 break;
21182 case GNU_PROPERTY_X86_FEATURE_2_X87:
21183 printf ("x87");
21184 break;
21185 case GNU_PROPERTY_X86_FEATURE_2_MMX:
21186 printf ("MMX");
21187 break;
21188 case GNU_PROPERTY_X86_FEATURE_2_XMM:
21189 printf ("XMM");
21190 break;
21191 case GNU_PROPERTY_X86_FEATURE_2_YMM:
21192 printf ("YMM");
21193 break;
21194 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
21195 printf ("ZMM");
21196 break;
21197 case GNU_PROPERTY_X86_FEATURE_2_TMM:
21198 printf ("TMM");
21199 break;
21200 case GNU_PROPERTY_X86_FEATURE_2_MASK:
21201 printf ("MASK");
21202 break;
21203 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
21204 printf ("FXSR");
21205 break;
21206 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
21207 printf ("XSAVE");
21208 break;
21209 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
21210 printf ("XSAVEOPT");
21211 break;
21212 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
21213 printf ("XSAVEC");
21214 break;
21215 default:
21216 printf (_("<unknown: %x>"), bit);
21217 break;
21219 if (bitmask)
21220 printf (", ");
21224 static void
21225 decode_aarch64_feature_1_and (unsigned int bitmask)
21227 while (bitmask)
21229 unsigned int bit = bitmask & (- bitmask);
21231 bitmask &= ~ bit;
21232 switch (bit)
21234 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
21235 printf ("BTI");
21236 break;
21238 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
21239 printf ("PAC");
21240 break;
21242 default:
21243 printf (_("<unknown: %x>"), bit);
21244 break;
21246 if (bitmask)
21247 printf (", ");
21251 static void
21252 decode_1_needed (unsigned int bitmask)
21254 while (bitmask)
21256 unsigned int bit = bitmask & (- bitmask);
21258 bitmask &= ~ bit;
21259 switch (bit)
21261 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
21262 printf ("indirect external access");
21263 break;
21264 default:
21265 printf (_("<unknown: %x>"), bit);
21266 break;
21268 if (bitmask)
21269 printf (", ");
21273 static void
21274 print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
21276 unsigned char * ptr = (unsigned char *) pnote->descdata;
21277 unsigned char * ptr_end = ptr + pnote->descsz;
21278 unsigned int size = is_32bit_elf ? 4 : 8;
21280 printf (_(" Properties: "));
21282 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
21284 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
21285 return;
21288 while (ptr < ptr_end)
21290 unsigned int j;
21291 unsigned int type;
21292 unsigned int datasz;
21294 if ((size_t) (ptr_end - ptr) < 8)
21296 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
21297 break;
21300 type = byte_get (ptr, 4);
21301 datasz = byte_get (ptr + 4, 4);
21303 ptr += 8;
21305 if (datasz > (size_t) (ptr_end - ptr))
21307 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
21308 type, datasz);
21309 break;
21312 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
21314 if (filedata->file_header.e_machine == EM_X86_64
21315 || filedata->file_header.e_machine == EM_IAMCU
21316 || filedata->file_header.e_machine == EM_386)
21318 unsigned int bitmask;
21320 if (datasz == 4)
21321 bitmask = byte_get (ptr, 4);
21322 else
21323 bitmask = 0;
21325 switch (type)
21327 case GNU_PROPERTY_X86_ISA_1_USED:
21328 if (datasz != 4)
21329 printf (_("x86 ISA used: <corrupt length: %#x> "),
21330 datasz);
21331 else
21333 printf ("x86 ISA used: ");
21334 decode_x86_isa (bitmask);
21336 goto next;
21338 case GNU_PROPERTY_X86_ISA_1_NEEDED:
21339 if (datasz != 4)
21340 printf (_("x86 ISA needed: <corrupt length: %#x> "),
21341 datasz);
21342 else
21344 printf ("x86 ISA needed: ");
21345 decode_x86_isa (bitmask);
21347 goto next;
21349 case GNU_PROPERTY_X86_FEATURE_1_AND:
21350 if (datasz != 4)
21351 printf (_("x86 feature: <corrupt length: %#x> "),
21352 datasz);
21353 else
21355 printf ("x86 feature: ");
21356 decode_x86_feature_1 (bitmask);
21358 goto next;
21360 case GNU_PROPERTY_X86_FEATURE_2_USED:
21361 if (datasz != 4)
21362 printf (_("x86 feature used: <corrupt length: %#x> "),
21363 datasz);
21364 else
21366 printf ("x86 feature used: ");
21367 decode_x86_feature_2 (bitmask);
21369 goto next;
21371 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
21372 if (datasz != 4)
21373 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
21374 else
21376 printf ("x86 feature needed: ");
21377 decode_x86_feature_2 (bitmask);
21379 goto next;
21381 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
21382 if (datasz != 4)
21383 printf (_("x86 ISA used: <corrupt length: %#x> "),
21384 datasz);
21385 else
21387 printf ("x86 ISA used: ");
21388 decode_x86_compat_isa (bitmask);
21390 goto next;
21392 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
21393 if (datasz != 4)
21394 printf (_("x86 ISA needed: <corrupt length: %#x> "),
21395 datasz);
21396 else
21398 printf ("x86 ISA needed: ");
21399 decode_x86_compat_isa (bitmask);
21401 goto next;
21403 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
21404 if (datasz != 4)
21405 printf (_("x86 ISA used: <corrupt length: %#x> "),
21406 datasz);
21407 else
21409 printf ("x86 ISA used: ");
21410 decode_x86_compat_2_isa (bitmask);
21412 goto next;
21414 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
21415 if (datasz != 4)
21416 printf (_("x86 ISA needed: <corrupt length: %#x> "),
21417 datasz);
21418 else
21420 printf ("x86 ISA needed: ");
21421 decode_x86_compat_2_isa (bitmask);
21423 goto next;
21425 default:
21426 break;
21429 else if (filedata->file_header.e_machine == EM_AARCH64)
21431 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
21433 printf ("AArch64 feature: ");
21434 if (datasz != 4)
21435 printf (_("<corrupt length: %#x> "), datasz);
21436 else
21437 decode_aarch64_feature_1_and (byte_get (ptr, 4));
21438 goto next;
21442 else
21444 switch (type)
21446 case GNU_PROPERTY_STACK_SIZE:
21447 printf (_("stack size: "));
21448 if (datasz != size)
21449 printf (_("<corrupt length: %#x> "), datasz);
21450 else
21451 printf ("%#" PRIx64, byte_get (ptr, size));
21452 goto next;
21454 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
21455 printf ("no copy on protected ");
21456 if (datasz)
21457 printf (_("<corrupt length: %#x> "), datasz);
21458 goto next;
21460 default:
21461 if ((type >= GNU_PROPERTY_UINT32_AND_LO
21462 && type <= GNU_PROPERTY_UINT32_AND_HI)
21463 || (type >= GNU_PROPERTY_UINT32_OR_LO
21464 && type <= GNU_PROPERTY_UINT32_OR_HI))
21466 switch (type)
21468 case GNU_PROPERTY_1_NEEDED:
21469 if (datasz != 4)
21470 printf (_("1_needed: <corrupt length: %#x> "),
21471 datasz);
21472 else
21474 unsigned int bitmask = byte_get (ptr, 4);
21475 printf ("1_needed: ");
21476 decode_1_needed (bitmask);
21478 goto next;
21480 default:
21481 break;
21483 if (type <= GNU_PROPERTY_UINT32_AND_HI)
21484 printf (_("UINT32_AND (%#x): "), type);
21485 else
21486 printf (_("UINT32_OR (%#x): "), type);
21487 if (datasz != 4)
21488 printf (_("<corrupt length: %#x> "), datasz);
21489 else
21490 printf ("%#x", (unsigned int) byte_get (ptr, 4));
21491 goto next;
21493 break;
21497 if (type < GNU_PROPERTY_LOPROC)
21498 printf (_("<unknown type %#x data: "), type);
21499 else if (type < GNU_PROPERTY_LOUSER)
21500 printf (_("<processor-specific type %#x data: "), type);
21501 else
21502 printf (_("<application-specific type %#x data: "), type);
21503 for (j = 0; j < datasz; ++j)
21504 printf ("%02x ", ptr[j] & 0xff);
21505 printf (">");
21507 next:
21508 ptr += ((datasz + (size - 1)) & ~ (size - 1));
21509 if (ptr == ptr_end)
21510 break;
21512 if (do_wide)
21513 printf (", ");
21514 else
21515 printf ("\n\t");
21518 printf ("\n");
21521 static bool
21522 print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
21524 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
21525 switch (pnote->type)
21527 case NT_GNU_BUILD_ID:
21529 size_t i;
21531 printf (_(" Build ID: "));
21532 for (i = 0; i < pnote->descsz; ++i)
21533 printf ("%02x", pnote->descdata[i] & 0xff);
21534 printf ("\n");
21536 break;
21538 case NT_GNU_ABI_TAG:
21540 unsigned int os, major, minor, subminor;
21541 const char *osname;
21543 /* PR 17531: file: 030-599401-0.004. */
21544 if (pnote->descsz < 16)
21546 printf (_(" <corrupt GNU_ABI_TAG>\n"));
21547 break;
21550 os = byte_get ((unsigned char *) pnote->descdata, 4);
21551 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
21552 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
21553 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
21555 switch (os)
21557 case GNU_ABI_TAG_LINUX:
21558 osname = "Linux";
21559 break;
21560 case GNU_ABI_TAG_HURD:
21561 osname = "Hurd";
21562 break;
21563 case GNU_ABI_TAG_SOLARIS:
21564 osname = "Solaris";
21565 break;
21566 case GNU_ABI_TAG_FREEBSD:
21567 osname = "FreeBSD";
21568 break;
21569 case GNU_ABI_TAG_NETBSD:
21570 osname = "NetBSD";
21571 break;
21572 case GNU_ABI_TAG_SYLLABLE:
21573 osname = "Syllable";
21574 break;
21575 case GNU_ABI_TAG_NACL:
21576 osname = "NaCl";
21577 break;
21578 default:
21579 osname = "Unknown";
21580 break;
21583 printf (_(" OS: %s, ABI: %d.%d.%d\n"), osname,
21584 major, minor, subminor);
21586 break;
21588 case NT_GNU_GOLD_VERSION:
21590 size_t i;
21592 printf (_(" Version: "));
21593 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
21594 printf ("%c", pnote->descdata[i]);
21595 printf ("\n");
21597 break;
21599 case NT_GNU_HWCAP:
21601 unsigned int num_entries, mask;
21603 /* Hardware capabilities information. Word 0 is the number of entries.
21604 Word 1 is a bitmask of enabled entries. The rest of the descriptor
21605 is a series of entries, where each entry is a single byte followed
21606 by a nul terminated string. The byte gives the bit number to test
21607 if enabled in the bitmask. */
21608 printf (_(" Hardware Capabilities: "));
21609 if (pnote->descsz < 8)
21611 error (_("<corrupt GNU_HWCAP>\n"));
21612 return false;
21614 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
21615 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
21616 printf (_("num entries: %d, enabled mask: %x\n"), num_entries, mask);
21617 /* FIXME: Add code to display the entries... */
21619 break;
21621 case NT_GNU_PROPERTY_TYPE_0:
21622 print_gnu_property_note (filedata, pnote);
21623 break;
21625 default:
21626 /* Handle unrecognised types. An error message should have already been
21627 created by get_gnu_elf_note_type(), so all that we need to do is to
21628 display the data. */
21630 size_t i;
21632 printf (_(" Description data: "));
21633 for (i = 0; i < pnote->descsz; ++i)
21634 printf ("%02x ", pnote->descdata[i] & 0xff);
21635 printf ("\n");
21637 break;
21640 return true;
21643 static const char *
21644 get_v850_elf_note_type (enum v850_notes n_type)
21646 static char buff[64];
21648 switch (n_type)
21650 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
21651 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
21652 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
21653 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
21654 case V850_NOTE_CACHE_INFO: return _("Use of cache");
21655 case V850_NOTE_MMU_INFO: return _("Use of MMU");
21656 default:
21657 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
21658 return buff;
21662 static bool
21663 print_v850_note (Elf_Internal_Note * pnote)
21665 unsigned int val;
21667 if (pnote->descsz != 4)
21668 return false;
21670 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
21672 if (val == 0)
21674 printf (_("not set\n"));
21675 return true;
21678 switch (pnote->type)
21680 case V850_NOTE_ALIGNMENT:
21681 switch (val)
21683 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
21684 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
21686 break;
21688 case V850_NOTE_DATA_SIZE:
21689 switch (val)
21691 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
21692 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
21694 break;
21696 case V850_NOTE_FPU_INFO:
21697 switch (val)
21699 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
21700 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
21702 break;
21704 case V850_NOTE_MMU_INFO:
21705 case V850_NOTE_CACHE_INFO:
21706 case V850_NOTE_SIMD_INFO:
21707 if (val == EF_RH850_SIMD)
21709 printf (_("yes\n"));
21710 return true;
21712 break;
21714 default:
21715 /* An 'unknown note type' message will already have been displayed. */
21716 break;
21719 printf (_("unknown value: %x\n"), val);
21720 return false;
21723 static bool
21724 process_netbsd_elf_note (Elf_Internal_Note * pnote)
21726 unsigned int version;
21728 switch (pnote->type)
21730 case NT_NETBSD_IDENT:
21731 if (pnote->descsz < 1)
21732 break;
21733 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21734 if ((version / 10000) % 100)
21735 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
21736 version, version / 100000000, (version / 1000000) % 100,
21737 (version / 10000) % 100 > 26 ? "Z" : "",
21738 'A' + (version / 10000) % 26);
21739 else
21740 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
21741 version, version / 100000000, (version / 1000000) % 100,
21742 (version / 100) % 100);
21743 return true;
21745 case NT_NETBSD_MARCH:
21746 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
21747 pnote->descdata);
21748 return true;
21750 case NT_NETBSD_PAX:
21751 if (pnote->descsz < 1)
21752 break;
21753 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21754 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
21755 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
21756 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
21757 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
21758 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
21759 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
21760 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
21761 return true;
21764 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
21765 pnote->descsz, pnote->type);
21766 return false;
21769 static const char *
21770 get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
21772 switch (e_type)
21774 case NT_FREEBSD_THRMISC:
21775 return _("NT_THRMISC (thrmisc structure)");
21776 case NT_FREEBSD_PROCSTAT_PROC:
21777 return _("NT_PROCSTAT_PROC (proc data)");
21778 case NT_FREEBSD_PROCSTAT_FILES:
21779 return _("NT_PROCSTAT_FILES (files data)");
21780 case NT_FREEBSD_PROCSTAT_VMMAP:
21781 return _("NT_PROCSTAT_VMMAP (vmmap data)");
21782 case NT_FREEBSD_PROCSTAT_GROUPS:
21783 return _("NT_PROCSTAT_GROUPS (groups data)");
21784 case NT_FREEBSD_PROCSTAT_UMASK:
21785 return _("NT_PROCSTAT_UMASK (umask data)");
21786 case NT_FREEBSD_PROCSTAT_RLIMIT:
21787 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
21788 case NT_FREEBSD_PROCSTAT_OSREL:
21789 return _("NT_PROCSTAT_OSREL (osreldate data)");
21790 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
21791 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
21792 case NT_FREEBSD_PROCSTAT_AUXV:
21793 return _("NT_PROCSTAT_AUXV (auxv data)");
21794 case NT_FREEBSD_PTLWPINFO:
21795 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
21796 case NT_FREEBSD_X86_SEGBASES:
21797 return _("NT_X86_SEGBASES (x86 segment base registers)");
21799 return get_note_type (filedata, e_type);
21802 static const char *
21803 get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
21805 static char buff[64];
21807 switch (e_type)
21809 case NT_NETBSDCORE_PROCINFO:
21810 /* NetBSD core "procinfo" structure. */
21811 return _("NetBSD procinfo structure");
21813 case NT_NETBSDCORE_AUXV:
21814 return _("NetBSD ELF auxiliary vector data");
21816 case NT_NETBSDCORE_LWPSTATUS:
21817 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
21819 default:
21820 /* As of Jan 2020 there are no other machine-independent notes
21821 defined for NetBSD core files. If the note type is less
21822 than the start of the machine-dependent note types, we don't
21823 understand it. */
21825 if (e_type < NT_NETBSDCORE_FIRSTMACH)
21827 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21828 return buff;
21830 break;
21833 switch (filedata->file_header.e_machine)
21835 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
21836 and PT_GETFPREGS == mach+2. */
21838 case EM_OLD_ALPHA:
21839 case EM_ALPHA:
21840 case EM_SPARC:
21841 case EM_SPARC32PLUS:
21842 case EM_SPARCV9:
21843 switch (e_type)
21845 case NT_NETBSDCORE_FIRSTMACH + 0:
21846 return _("PT_GETREGS (reg structure)");
21847 case NT_NETBSDCORE_FIRSTMACH + 2:
21848 return _("PT_GETFPREGS (fpreg structure)");
21849 default:
21850 break;
21852 break;
21854 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
21855 There's also old PT___GETREGS40 == mach + 1 for old reg
21856 structure which lacks GBR. */
21857 case EM_SH:
21858 switch (e_type)
21860 case NT_NETBSDCORE_FIRSTMACH + 1:
21861 return _("PT___GETREGS40 (old reg structure)");
21862 case NT_NETBSDCORE_FIRSTMACH + 3:
21863 return _("PT_GETREGS (reg structure)");
21864 case NT_NETBSDCORE_FIRSTMACH + 5:
21865 return _("PT_GETFPREGS (fpreg structure)");
21866 default:
21867 break;
21869 break;
21871 /* On all other arch's, PT_GETREGS == mach+1 and
21872 PT_GETFPREGS == mach+3. */
21873 default:
21874 switch (e_type)
21876 case NT_NETBSDCORE_FIRSTMACH + 1:
21877 return _("PT_GETREGS (reg structure)");
21878 case NT_NETBSDCORE_FIRSTMACH + 3:
21879 return _("PT_GETFPREGS (fpreg structure)");
21880 default:
21881 break;
21885 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
21886 e_type - NT_NETBSDCORE_FIRSTMACH);
21887 return buff;
21890 static const char *
21891 get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
21893 switch (e_type)
21895 case NT_OPENBSD_PROCINFO:
21896 return _("OpenBSD procinfo structure");
21897 case NT_OPENBSD_AUXV:
21898 return _("OpenBSD ELF auxiliary vector data");
21899 case NT_OPENBSD_REGS:
21900 return _("OpenBSD regular registers");
21901 case NT_OPENBSD_FPREGS:
21902 return _("OpenBSD floating point registers");
21903 case NT_OPENBSD_WCOOKIE:
21904 return _("OpenBSD window cookie");
21907 return get_note_type (filedata, e_type);
21910 static const char *
21911 get_qnx_elfcore_note_type (Filedata * filedata, unsigned e_type)
21913 switch (e_type)
21915 case QNT_DEBUG_FULLPATH:
21916 return _("QNX debug fullpath");
21917 case QNT_DEBUG_RELOC:
21918 return _("QNX debug relocation");
21919 case QNT_STACK:
21920 return _("QNX stack");
21921 case QNT_GENERATOR:
21922 return _("QNX generator");
21923 case QNT_DEFAULT_LIB:
21924 return _("QNX default library");
21925 case QNT_CORE_SYSINFO:
21926 return _("QNX core sysinfo");
21927 case QNT_CORE_INFO:
21928 return _("QNX core info");
21929 case QNT_CORE_STATUS:
21930 return _("QNX core status");
21931 case QNT_CORE_GREG:
21932 return _("QNX general registers");
21933 case QNT_CORE_FPREG:
21934 return _("QNX floating point registers");
21935 case QNT_LINK_MAP:
21936 return _("QNX link map");
21939 return get_note_type (filedata, e_type);
21942 static const char *
21943 get_stapsdt_note_type (unsigned e_type)
21945 static char buff[64];
21947 switch (e_type)
21949 case NT_STAPSDT:
21950 return _("NT_STAPSDT (SystemTap probe descriptors)");
21952 default:
21953 break;
21956 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21957 return buff;
21960 static bool
21961 print_stapsdt_note (Elf_Internal_Note *pnote)
21963 size_t len, maxlen;
21964 size_t addr_size = is_32bit_elf ? 4 : 8;
21965 char *data = pnote->descdata;
21966 char *data_end = pnote->descdata + pnote->descsz;
21967 uint64_t pc, base_addr, semaphore;
21968 char *provider, *probe, *arg_fmt;
21970 if (pnote->descsz < (addr_size * 3))
21971 goto stapdt_note_too_small;
21973 pc = byte_get ((unsigned char *) data, addr_size);
21974 data += addr_size;
21976 base_addr = byte_get ((unsigned char *) data, addr_size);
21977 data += addr_size;
21979 semaphore = byte_get ((unsigned char *) data, addr_size);
21980 data += addr_size;
21982 if (data >= data_end)
21983 goto stapdt_note_too_small;
21984 maxlen = data_end - data;
21985 len = strnlen (data, maxlen);
21986 if (len < maxlen)
21988 provider = data;
21989 data += len + 1;
21991 else
21992 goto stapdt_note_too_small;
21994 if (data >= data_end)
21995 goto stapdt_note_too_small;
21996 maxlen = data_end - data;
21997 len = strnlen (data, maxlen);
21998 if (len < maxlen)
22000 probe = data;
22001 data += len + 1;
22003 else
22004 goto stapdt_note_too_small;
22006 if (data >= data_end)
22007 goto stapdt_note_too_small;
22008 maxlen = data_end - data;
22009 len = strnlen (data, maxlen);
22010 if (len < maxlen)
22012 arg_fmt = data;
22013 data += len + 1;
22015 else
22016 goto stapdt_note_too_small;
22018 printf (_(" Provider: %s\n"), provider);
22019 printf (_(" Name: %s\n"), probe);
22020 printf (_(" Location: "));
22021 print_vma (pc, FULL_HEX);
22022 printf (_(", Base: "));
22023 print_vma (base_addr, FULL_HEX);
22024 printf (_(", Semaphore: "));
22025 print_vma (semaphore, FULL_HEX);
22026 printf ("\n");
22027 printf (_(" Arguments: %s\n"), arg_fmt);
22029 return data == data_end;
22031 stapdt_note_too_small:
22032 printf (_(" <corrupt - note is too small>\n"));
22033 error (_("corrupt stapdt note - the data size is too small\n"));
22034 return false;
22037 static bool
22038 print_fdo_note (Elf_Internal_Note * pnote)
22040 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
22042 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
22043 return true;
22045 if (pnote->descsz > 0 && pnote->type == FDO_DLOPEN_METADATA)
22047 printf (_(" Dlopen Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
22048 return true;
22050 return false;
22053 static const char *
22054 get_ia64_vms_note_type (unsigned e_type)
22056 static char buff[64];
22058 switch (e_type)
22060 case NT_VMS_MHD:
22061 return _("NT_VMS_MHD (module header)");
22062 case NT_VMS_LNM:
22063 return _("NT_VMS_LNM (language name)");
22064 case NT_VMS_SRC:
22065 return _("NT_VMS_SRC (source files)");
22066 case NT_VMS_TITLE:
22067 return "NT_VMS_TITLE";
22068 case NT_VMS_EIDC:
22069 return _("NT_VMS_EIDC (consistency check)");
22070 case NT_VMS_FPMODE:
22071 return _("NT_VMS_FPMODE (FP mode)");
22072 case NT_VMS_LINKTIME:
22073 return "NT_VMS_LINKTIME";
22074 case NT_VMS_IMGNAM:
22075 return _("NT_VMS_IMGNAM (image name)");
22076 case NT_VMS_IMGID:
22077 return _("NT_VMS_IMGID (image id)");
22078 case NT_VMS_LINKID:
22079 return _("NT_VMS_LINKID (link id)");
22080 case NT_VMS_IMGBID:
22081 return _("NT_VMS_IMGBID (build id)");
22082 case NT_VMS_GSTNAM:
22083 return _("NT_VMS_GSTNAM (sym table name)");
22084 case NT_VMS_ORIG_DYN:
22085 return "NT_VMS_ORIG_DYN";
22086 case NT_VMS_PATCHTIME:
22087 return "NT_VMS_PATCHTIME";
22088 default:
22089 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
22090 return buff;
22094 static bool
22095 print_ia64_vms_note (Elf_Internal_Note * pnote)
22097 unsigned int maxlen = pnote->descsz;
22099 if (maxlen < 2 || maxlen != pnote->descsz)
22100 goto desc_size_fail;
22102 switch (pnote->type)
22104 case NT_VMS_MHD:
22105 if (maxlen <= 36)
22106 goto desc_size_fail;
22108 size_t l = strnlen (pnote->descdata + 34, maxlen - 34);
22110 printf (_(" Creation date : %.17s\n"), pnote->descdata);
22111 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
22112 if (l + 34 < maxlen)
22114 printf (_(" Module name : %s\n"), pnote->descdata + 34);
22115 if (l + 35 < maxlen)
22116 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
22117 else
22118 printf (_(" Module version : <missing>\n"));
22120 else
22122 printf (_(" Module name : <missing>\n"));
22123 printf (_(" Module version : <missing>\n"));
22125 break;
22127 case NT_VMS_LNM:
22128 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
22129 break;
22131 case NT_VMS_FPMODE:
22132 printf (_(" Floating Point mode: "));
22133 if (maxlen < 8)
22134 goto desc_size_fail;
22135 /* FIXME: Generate an error if descsz > 8 ? */
22137 printf ("0x%016" PRIx64 "\n",
22138 byte_get ((unsigned char *) pnote->descdata, 8));
22139 break;
22141 case NT_VMS_LINKTIME:
22142 printf (_(" Link time: "));
22143 if (maxlen < 8)
22144 goto desc_size_fail;
22145 /* FIXME: Generate an error if descsz > 8 ? */
22147 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
22148 printf ("\n");
22149 break;
22151 case NT_VMS_PATCHTIME:
22152 printf (_(" Patch time: "));
22153 if (maxlen < 8)
22154 goto desc_size_fail;
22155 /* FIXME: Generate an error if descsz > 8 ? */
22157 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
22158 printf ("\n");
22159 break;
22161 case NT_VMS_ORIG_DYN:
22162 if (maxlen < 34)
22163 goto desc_size_fail;
22165 printf (_(" Major id: %u, minor id: %u\n"),
22166 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
22167 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
22168 printf (_(" Last modified : "));
22169 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
22170 printf (_("\n Link flags : "));
22171 printf ("0x%016" PRIx64 "\n",
22172 byte_get ((unsigned char *) pnote->descdata + 16, 8));
22173 printf (_(" Header flags: 0x%08x\n"),
22174 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
22175 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
22176 break;
22178 case NT_VMS_IMGNAM:
22179 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
22180 break;
22182 case NT_VMS_GSTNAM:
22183 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
22184 break;
22186 case NT_VMS_IMGID:
22187 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
22188 break;
22190 case NT_VMS_LINKID:
22191 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
22192 break;
22194 default:
22195 return false;
22198 return true;
22200 desc_size_fail:
22201 printf (_(" <corrupt - data size is too small>\n"));
22202 error (_("corrupt IA64 note: data size is too small\n"));
22203 return false;
22206 struct build_attr_cache {
22207 Filedata *filedata;
22208 char *strtab;
22209 uint64_t strtablen;
22210 Elf_Internal_Sym *symtab;
22211 uint64_t nsyms;
22212 } ba_cache;
22214 /* Find the symbol associated with a build attribute that is attached
22215 to address OFFSET. If PNAME is non-NULL then store the name of
22216 the symbol (if found) in the provided pointer, Returns NULL if a
22217 symbol could not be found. */
22219 static Elf_Internal_Sym *
22220 get_symbol_for_build_attribute (Filedata *filedata,
22221 uint64_t offset,
22222 bool is_open_attr,
22223 const char **pname)
22225 Elf_Internal_Sym *saved_sym = NULL;
22226 Elf_Internal_Sym *sym;
22228 if (filedata->section_headers != NULL
22229 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
22231 Elf_Internal_Shdr * symsec;
22233 free (ba_cache.strtab);
22234 ba_cache.strtab = NULL;
22235 free (ba_cache.symtab);
22236 ba_cache.symtab = NULL;
22238 /* Load the symbol and string sections. */
22239 for (symsec = filedata->section_headers;
22240 symsec < filedata->section_headers + filedata->file_header.e_shnum;
22241 symsec ++)
22243 if (symsec->sh_type == SHT_SYMTAB
22244 && get_symtab (filedata, symsec,
22245 &ba_cache.symtab, &ba_cache.nsyms,
22246 &ba_cache.strtab, &ba_cache.strtablen))
22247 break;
22249 ba_cache.filedata = filedata;
22252 if (ba_cache.symtab == NULL)
22253 return NULL;
22255 /* Find a symbol whose value matches offset. */
22256 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
22257 if (sym->st_value == offset)
22259 if (sym->st_name >= ba_cache.strtablen)
22260 /* Huh ? This should not happen. */
22261 continue;
22263 if (ba_cache.strtab[sym->st_name] == 0)
22264 continue;
22266 /* The AArch64, ARM and RISC-V architectures define mapping symbols
22267 (eg $d, $x, $t) which we want to ignore. */
22268 if (ba_cache.strtab[sym->st_name] == '$'
22269 && ba_cache.strtab[sym->st_name + 1] != 0
22270 && ba_cache.strtab[sym->st_name + 2] == 0)
22271 continue;
22273 if (is_open_attr)
22275 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
22276 and FILE or OBJECT symbols over NOTYPE symbols. We skip
22277 FUNC symbols entirely. */
22278 switch (ELF_ST_TYPE (sym->st_info))
22280 case STT_OBJECT:
22281 case STT_FILE:
22282 saved_sym = sym;
22283 if (sym->st_size)
22285 /* If the symbol has a size associated
22286 with it then we can stop searching. */
22287 sym = ba_cache.symtab + ba_cache.nsyms;
22289 continue;
22291 case STT_FUNC:
22292 /* Ignore function symbols. */
22293 continue;
22295 default:
22296 break;
22299 switch (ELF_ST_BIND (sym->st_info))
22301 case STB_GLOBAL:
22302 if (saved_sym == NULL
22303 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
22304 saved_sym = sym;
22305 break;
22307 case STB_LOCAL:
22308 if (saved_sym == NULL)
22309 saved_sym = sym;
22310 break;
22312 default:
22313 break;
22316 else
22318 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
22319 continue;
22321 saved_sym = sym;
22322 break;
22326 if (saved_sym && pname)
22327 * pname = ba_cache.strtab + saved_sym->st_name;
22329 return saved_sym;
22332 /* Returns true iff addr1 and addr2 are in the same section. */
22334 static bool
22335 same_section (Filedata * filedata, uint64_t addr1, uint64_t addr2)
22337 Elf_Internal_Shdr * a1;
22338 Elf_Internal_Shdr * a2;
22340 a1 = find_section_by_address (filedata, addr1);
22341 a2 = find_section_by_address (filedata, addr2);
22343 return a1 == a2 && a1 != NULL;
22346 static bool
22347 print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
22348 Filedata * filedata)
22350 static uint64_t global_offset = 0;
22351 static uint64_t global_end = 0;
22352 static uint64_t func_offset = 0;
22353 static uint64_t func_end = 0;
22355 Elf_Internal_Sym *sym;
22356 const char *name;
22357 uint64_t start;
22358 uint64_t end;
22359 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
22361 switch (pnote->descsz)
22363 case 0:
22364 /* A zero-length description means that the range of
22365 the previous note of the same type should be used. */
22366 if (is_open_attr)
22368 if (global_end > global_offset)
22369 printf (_(" Applies to region from %#" PRIx64
22370 " to %#" PRIx64 "\n"), global_offset, global_end);
22371 else
22372 printf (_(" Applies to region from %#" PRIx64
22373 "\n"), global_offset);
22375 else
22377 if (func_end > func_offset)
22378 printf (_(" Applies to region from %#" PRIx64
22379 " to %#" PRIx64 "\n"), func_offset, func_end);
22380 else
22381 printf (_(" Applies to region from %#" PRIx64
22382 "\n"), func_offset);
22384 return true;
22386 case 4:
22387 start = byte_get ((unsigned char *) pnote->descdata, 4);
22388 end = 0;
22389 break;
22391 case 8:
22392 start = byte_get ((unsigned char *) pnote->descdata, 4);
22393 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
22394 break;
22396 case 16:
22397 start = byte_get ((unsigned char *) pnote->descdata, 8);
22398 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
22399 break;
22401 default:
22402 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
22403 printf (_(" <invalid descsz>"));
22404 return false;
22407 name = NULL;
22408 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
22409 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
22410 in order to avoid them being confused with the start address of the
22411 first function in the file... */
22412 if (sym == NULL && is_open_attr)
22413 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
22414 & name);
22416 if (end == 0 && sym != NULL && sym->st_size > 0)
22417 end = start + sym->st_size;
22419 if (is_open_attr)
22421 /* FIXME: Need to properly allow for section alignment.
22422 16 is just the alignment used on x86_64. */
22423 if (global_end > 0
22424 && start > BFD_ALIGN (global_end, 16)
22425 /* Build notes are not guaranteed to be organised in order of
22426 increasing address, but we should find the all of the notes
22427 for one section in the same place. */
22428 && same_section (filedata, start, global_end))
22429 warn (_("Gap in build notes detected from %#" PRIx64
22430 " to %#" PRIx64 "\n"),
22431 global_end + 1, start - 1);
22433 printf (_(" Applies to region from %#" PRIx64), start);
22434 global_offset = start;
22436 if (end)
22438 printf (_(" to %#" PRIx64), end);
22439 global_end = end;
22442 else
22444 printf (_(" Applies to region from %#" PRIx64), start);
22445 func_offset = start;
22447 if (end)
22449 printf (_(" to %#" PRIx64), end);
22450 func_end = end;
22454 if (sym && name)
22455 printf (_(" (%s)"), name);
22457 printf ("\n");
22458 return true;
22461 static bool
22462 print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
22464 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
22465 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
22466 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
22467 char name_type;
22468 char name_attribute;
22469 const char * expected_types;
22470 const char * name = pnote->namedata;
22471 const char * text;
22472 signed int left;
22474 if (name == NULL || pnote->namesz < 2)
22476 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
22477 print_symbol_name (-20, _(" <corrupt name>"));
22478 return false;
22481 if (do_wide)
22482 left = 28;
22483 else
22484 left = 20;
22486 /* Version 2 of the spec adds a "GA" prefix to the name field. */
22487 if (name[0] == 'G' && name[1] == 'A')
22489 if (pnote->namesz < 4)
22491 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
22492 print_symbol_name (-20, _(" <corrupt name>"));
22493 return false;
22496 printf ("GA");
22497 name += 2;
22498 left -= 2;
22501 switch ((name_type = * name))
22503 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
22504 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
22505 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
22506 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
22507 printf ("%c", * name);
22508 left --;
22509 break;
22510 default:
22511 error (_("unrecognised attribute type in name field: %d\n"), name_type);
22512 print_symbol_name (-20, _("<unknown name type>"));
22513 return false;
22516 ++ name;
22517 text = NULL;
22519 switch ((name_attribute = * name))
22521 case GNU_BUILD_ATTRIBUTE_VERSION:
22522 text = _("<version>");
22523 expected_types = string_expected;
22524 ++ name;
22525 break;
22526 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
22527 text = _("<stack prot>");
22528 expected_types = "!+*";
22529 ++ name;
22530 break;
22531 case GNU_BUILD_ATTRIBUTE_RELRO:
22532 text = _("<relro>");
22533 expected_types = bool_expected;
22534 ++ name;
22535 break;
22536 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
22537 text = _("<stack size>");
22538 expected_types = number_expected;
22539 ++ name;
22540 break;
22541 case GNU_BUILD_ATTRIBUTE_TOOL:
22542 text = _("<tool>");
22543 expected_types = string_expected;
22544 ++ name;
22545 break;
22546 case GNU_BUILD_ATTRIBUTE_ABI:
22547 text = _("<ABI>");
22548 expected_types = "$*";
22549 ++ name;
22550 break;
22551 case GNU_BUILD_ATTRIBUTE_PIC:
22552 text = _("<PIC>");
22553 expected_types = number_expected;
22554 ++ name;
22555 break;
22556 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
22557 text = _("<short enum>");
22558 expected_types = bool_expected;
22559 ++ name;
22560 break;
22561 default:
22562 if (ISPRINT (* name))
22564 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
22566 if (len > left && ! do_wide)
22567 len = left;
22568 printf ("%.*s:", len, name);
22569 left -= len;
22570 name += len;
22572 else
22574 static char tmpbuf [128];
22576 error (_("unrecognised byte in name field: %d\n"), * name);
22577 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
22578 text = tmpbuf;
22579 name ++;
22581 expected_types = "*$!+";
22582 break;
22585 if (text)
22586 left -= printf ("%s", text);
22588 if (strchr (expected_types, name_type) == NULL)
22589 warn (_("attribute does not have an expected type (%c)\n"), name_type);
22591 if ((size_t) (name - pnote->namedata) > pnote->namesz)
22593 error (_("corrupt name field: namesz: %lu but parsing gets to %td\n"),
22594 pnote->namesz,
22595 name - pnote->namedata);
22596 return false;
22599 if (left < 1 && ! do_wide)
22600 return true;
22602 switch (name_type)
22604 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
22606 unsigned int bytes;
22607 uint64_t val = 0;
22608 unsigned int shift = 0;
22609 char *decoded = NULL;
22611 bytes = pnote->namesz - (name - pnote->namedata);
22612 if (bytes > 0)
22613 /* The -1 is because the name field is always 0 terminated, and we
22614 want to be able to ensure that the shift in the while loop below
22615 will not overflow. */
22616 -- bytes;
22618 if (bytes > sizeof (val))
22620 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
22621 bytes);
22622 bytes = sizeof (val);
22624 /* We do not bother to warn if bytes == 0 as this can
22625 happen with some early versions of the gcc plugin. */
22627 while (bytes --)
22629 uint64_t byte = *name++ & 0xff;
22631 val |= byte << shift;
22632 shift += 8;
22635 switch (name_attribute)
22637 case GNU_BUILD_ATTRIBUTE_PIC:
22638 switch (val)
22640 case 0: decoded = "static"; break;
22641 case 1: decoded = "pic"; break;
22642 case 2: decoded = "PIC"; break;
22643 case 3: decoded = "pie"; break;
22644 case 4: decoded = "PIE"; break;
22645 default: break;
22647 break;
22648 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
22649 switch (val)
22651 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
22652 case 0: decoded = "off"; break;
22653 case 1: decoded = "on"; break;
22654 case 2: decoded = "all"; break;
22655 case 3: decoded = "strong"; break;
22656 case 4: decoded = "explicit"; break;
22657 default: break;
22659 break;
22660 default:
22661 break;
22664 if (decoded != NULL)
22666 print_symbol_name (-left, decoded);
22667 left = 0;
22669 else if (val == 0)
22671 printf ("0x0");
22672 left -= 3;
22674 else
22676 if (do_wide)
22677 left -= printf ("0x%" PRIx64, val);
22678 else
22679 left -= printf ("0x%-.*" PRIx64, left, val);
22682 break;
22683 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
22684 left -= print_symbol_name (- left, name);
22685 break;
22686 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
22687 left -= print_symbol_name (- left, "true");
22688 break;
22689 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
22690 left -= print_symbol_name (- left, "false");
22691 break;
22694 if (do_wide && left > 0)
22695 printf ("%-*s", left, " ");
22697 return true;
22700 /* Print the contents of PNOTE as hex. */
22702 static void
22703 print_note_contents_hex (Elf_Internal_Note *pnote)
22705 if (pnote->descsz)
22707 size_t i;
22709 printf (_(" description data: "));
22710 for (i = 0; i < pnote->descsz; i++)
22711 printf ("%02x ", pnote->descdata[i] & 0xff);
22712 if (!do_wide)
22713 printf ("\n");
22716 if (do_wide)
22717 printf ("\n");
22720 #if defined HAVE_MSGPACK
22722 static void
22723 print_indents (int n)
22725 printf (" ");
22727 for (int i = 0; i < n; i++)
22728 printf (" ");
22731 /* Print OBJ in human-readable form. */
22733 static void
22734 dump_msgpack_obj (const msgpack_object *obj, int indent)
22736 switch (obj->type)
22738 case MSGPACK_OBJECT_NIL:
22739 printf ("(nil)");
22740 break;
22742 case MSGPACK_OBJECT_BOOLEAN:
22743 printf ("%s", obj->via.boolean ? "true" : "false");
22744 break;
22746 case MSGPACK_OBJECT_POSITIVE_INTEGER:
22747 printf ("%" PRIu64, obj->via.u64);
22748 break;
22750 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
22751 printf ("%" PRIi64, obj->via.i64);
22752 break;
22754 case MSGPACK_OBJECT_FLOAT32:
22755 case MSGPACK_OBJECT_FLOAT64:
22756 printf ("%f", obj->via.f64);
22757 break;
22759 case MSGPACK_OBJECT_STR:
22760 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
22761 break;
22763 case MSGPACK_OBJECT_ARRAY:
22765 const msgpack_object_array *array = &obj->via.array;
22767 printf ("[\n");
22768 ++indent;
22770 for (uint32_t i = 0; i < array->size; ++i)
22772 const msgpack_object *item = &array->ptr[i];
22774 print_indents (indent);
22775 dump_msgpack_obj (item, indent);
22776 printf (",\n");
22779 --indent;
22780 print_indents (indent);
22781 printf ("]");
22782 break;
22784 break;
22786 case MSGPACK_OBJECT_MAP:
22788 const msgpack_object_map *map = &obj->via.map;
22790 printf ("{\n");
22791 ++indent;
22793 for (uint32_t i = 0; i < map->size; ++i)
22795 const msgpack_object_kv *kv = &map->ptr[i];
22796 const msgpack_object *key = &kv->key;
22797 const msgpack_object *val = &kv->val;
22799 print_indents (indent);
22800 dump_msgpack_obj (key, indent);
22801 printf (": ");
22802 dump_msgpack_obj (val, indent);
22804 printf (",\n");
22807 --indent;
22808 print_indents (indent);
22809 printf ("}");
22811 break;
22814 case MSGPACK_OBJECT_BIN:
22815 printf ("(bin)");
22816 break;
22818 case MSGPACK_OBJECT_EXT:
22819 printf ("(ext)");
22820 break;
22824 static void
22825 dump_msgpack (const msgpack_unpacked *msg)
22827 print_indents (0);
22828 dump_msgpack_obj (&msg->data, 0);
22829 printf ("\n");
22832 #endif /* defined HAVE_MSGPACK */
22834 static bool
22835 print_amdgpu_note (Elf_Internal_Note *pnote)
22837 #if defined HAVE_MSGPACK
22838 /* If msgpack is available, decode and dump the note's content. */
22839 bool ret;
22840 msgpack_unpacked msg;
22841 msgpack_unpack_return msgpack_ret;
22843 assert (pnote->type == NT_AMDGPU_METADATA);
22845 msgpack_unpacked_init (&msg);
22846 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
22847 NULL);
22849 switch (msgpack_ret)
22851 case MSGPACK_UNPACK_SUCCESS:
22852 dump_msgpack (&msg);
22853 ret = true;
22854 break;
22856 default:
22857 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
22858 ret = false;
22859 break;
22862 msgpack_unpacked_destroy (&msg);
22863 return ret;
22864 #else
22865 /* msgpack is not available, dump contents as hex. */
22866 print_note_contents_hex (pnote);
22867 return true;
22868 #endif
22871 static bool
22872 print_qnx_note (Elf_Internal_Note *pnote)
22874 switch (pnote->type)
22876 case QNT_STACK:
22877 if (pnote->descsz != 12)
22878 goto desc_size_fail;
22880 printf (_(" Stack Size: 0x%" PRIx32 "\n"),
22881 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4));
22882 printf (_(" Stack allocated: %" PRIx32 "\n"),
22883 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
22884 printf (_(" Executable: %s\n"),
22885 ((unsigned) byte_get ((unsigned char *) pnote->descdata + 8, 1)) ? "no": "yes");
22886 break;
22888 default:
22889 print_note_contents_hex(pnote);
22891 return true;
22893 desc_size_fail:
22894 printf (_(" <corrupt - data size is too small>\n"));
22895 error (_("corrupt QNX note: data size is too small\n"));
22896 return false;
22900 /* Note that by the ELF standard, the name field is already null byte
22901 terminated, and namesz includes the terminating null byte.
22902 I.E. the value of namesz for the name "FSF" is 4.
22904 If the value of namesz is zero, there is no name present. */
22906 static bool
22907 process_note (Elf_Internal_Note * pnote,
22908 Filedata * filedata)
22910 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
22911 const char * nt;
22913 if (pnote->namesz == 0)
22914 /* If there is no note name, then use the default set of
22915 note type strings. */
22916 nt = get_note_type (filedata, pnote->type);
22918 else if (startswith (pnote->namedata, "GNU"))
22919 /* GNU-specific object file notes. */
22920 nt = get_gnu_elf_note_type (pnote->type);
22922 else if (startswith (pnote->namedata, "AMDGPU"))
22923 /* AMDGPU-specific object file notes. */
22924 nt = get_amdgpu_elf_note_type (pnote->type);
22926 else if (startswith (pnote->namedata, "FreeBSD"))
22927 /* FreeBSD-specific core file notes. */
22928 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
22930 else if (startswith (pnote->namedata, "NetBSD-CORE"))
22931 /* NetBSD-specific core file notes. */
22932 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
22934 else if (startswith (pnote->namedata, "NetBSD"))
22935 /* NetBSD-specific core file notes. */
22936 return process_netbsd_elf_note (pnote);
22938 else if (startswith (pnote->namedata, "PaX"))
22939 /* NetBSD-specific core file notes. */
22940 return process_netbsd_elf_note (pnote);
22942 else if (startswith (pnote->namedata, "OpenBSD"))
22943 /* OpenBSD-specific core file notes. */
22944 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
22946 else if (startswith (pnote->namedata, "QNX"))
22947 /* QNX-specific core file notes. */
22948 nt = get_qnx_elfcore_note_type (filedata, pnote->type);
22950 else if (startswith (pnote->namedata, "SPU/"))
22952 /* SPU-specific core file notes. */
22953 nt = pnote->namedata + 4;
22954 name = "SPU";
22957 else if (startswith (pnote->namedata, "IPF/VMS"))
22958 /* VMS/ia64-specific file notes. */
22959 nt = get_ia64_vms_note_type (pnote->type);
22961 else if (startswith (pnote->namedata, "stapsdt"))
22962 nt = get_stapsdt_note_type (pnote->type);
22964 else
22965 /* Don't recognize this note name; just use the default set of
22966 note type strings. */
22967 nt = get_note_type (filedata, pnote->type);
22969 printf (" ");
22971 if (((startswith (pnote->namedata, "GA")
22972 && strchr ("*$!+", pnote->namedata[2]) != NULL)
22973 || strchr ("*$!+", pnote->namedata[0]) != NULL)
22974 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
22975 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
22976 print_gnu_build_attribute_name (pnote);
22977 else
22978 print_symbol_name (-20, name);
22980 if (do_wide)
22981 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
22982 else
22983 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
22985 if (startswith (pnote->namedata, "IPF/VMS"))
22986 return print_ia64_vms_note (pnote);
22987 else if (startswith (pnote->namedata, "GNU"))
22988 return print_gnu_note (filedata, pnote);
22989 else if (startswith (pnote->namedata, "stapsdt"))
22990 return print_stapsdt_note (pnote);
22991 else if (startswith (pnote->namedata, "CORE"))
22992 return print_core_note (pnote);
22993 else if (startswith (pnote->namedata, "FDO"))
22994 return print_fdo_note (pnote);
22995 else if (((startswith (pnote->namedata, "GA")
22996 && strchr ("*$!+", pnote->namedata[2]) != NULL)
22997 || strchr ("*$!+", pnote->namedata[0]) != NULL)
22998 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
22999 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
23000 return print_gnu_build_attribute_description (pnote, filedata);
23001 else if (startswith (pnote->namedata, "AMDGPU")
23002 && pnote->type == NT_AMDGPU_METADATA)
23003 return print_amdgpu_note (pnote);
23004 else if (startswith (pnote->namedata, "QNX"))
23005 return print_qnx_note (pnote);
23007 print_note_contents_hex (pnote);
23008 return true;
23011 static bool
23012 process_notes_at (Filedata * filedata,
23013 Elf_Internal_Shdr * section,
23014 uint64_t offset,
23015 uint64_t length,
23016 uint64_t align)
23018 Elf_External_Note *pnotes;
23019 Elf_External_Note *external;
23020 char *end;
23021 bool res = true;
23023 if (length <= 0)
23024 return false;
23026 if (section)
23028 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
23029 if (pnotes)
23031 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
23033 free (pnotes);
23034 return false;
23038 else
23039 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
23040 _("notes"));
23042 if (pnotes == NULL)
23043 return false;
23045 external = pnotes;
23047 if (filedata->is_separate)
23048 printf (_("In linked file '%s': "), filedata->file_name);
23049 else
23050 printf ("\n");
23051 if (section)
23052 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
23053 else
23054 printf (_("Displaying notes found at file offset 0x%08" PRIx64
23055 " with length 0x%08" PRIx64 ":\n"),
23056 offset, length);
23058 /* NB: Some note sections may have alignment value of 0 or 1. gABI
23059 specifies that notes should be aligned to 4 bytes in 32-bit
23060 objects and to 8 bytes in 64-bit objects. As a Linux extension,
23061 we also support 4 byte alignment in 64-bit objects. If section
23062 alignment is less than 4, we treate alignment as 4 bytes. */
23063 if (align < 4)
23064 align = 4;
23065 else if (align != 4 && align != 8)
23067 warn (_("Corrupt note: alignment %" PRId64 ", expecting 4 or 8\n"),
23068 align);
23069 free (pnotes);
23070 return false;
23073 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
23075 end = (char *) pnotes + length;
23076 while ((char *) external < end)
23078 Elf_Internal_Note inote;
23079 size_t min_notesz;
23080 char * next;
23081 char * temp = NULL;
23082 size_t data_remaining = end - (char *) external;
23084 if (!is_ia64_vms (filedata))
23086 /* PR binutils/15191
23087 Make sure that there is enough data to read. */
23088 min_notesz = offsetof (Elf_External_Note, name);
23089 if (data_remaining < min_notesz)
23091 warn (ngettext ("Corrupt note: only %zd byte remains, "
23092 "not enough for a full note\n",
23093 "Corrupt note: only %zd bytes remain, "
23094 "not enough for a full note\n",
23095 data_remaining),
23096 data_remaining);
23097 break;
23099 data_remaining -= min_notesz;
23101 inote.type = BYTE_GET (external->type);
23102 inote.namesz = BYTE_GET (external->namesz);
23103 inote.namedata = external->name;
23104 inote.descsz = BYTE_GET (external->descsz);
23105 inote.descdata = ((char *) external
23106 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
23107 inote.descpos = offset + (inote.descdata - (char *) pnotes);
23108 next = ((char *) external
23109 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
23111 else
23113 Elf64_External_VMS_Note *vms_external;
23115 /* PR binutils/15191
23116 Make sure that there is enough data to read. */
23117 min_notesz = offsetof (Elf64_External_VMS_Note, name);
23118 if (data_remaining < min_notesz)
23120 warn (ngettext ("Corrupt note: only %zd byte remains, "
23121 "not enough for a full note\n",
23122 "Corrupt note: only %zd bytes remain, "
23123 "not enough for a full note\n",
23124 data_remaining),
23125 data_remaining);
23126 break;
23128 data_remaining -= min_notesz;
23130 vms_external = (Elf64_External_VMS_Note *) external;
23131 inote.type = BYTE_GET (vms_external->type);
23132 inote.namesz = BYTE_GET (vms_external->namesz);
23133 inote.namedata = vms_external->name;
23134 inote.descsz = BYTE_GET (vms_external->descsz);
23135 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
23136 inote.descpos = offset + (inote.descdata - (char *) pnotes);
23137 next = inote.descdata + align_power (inote.descsz, 3);
23140 /* PR 17531: file: 3443835e. */
23141 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
23142 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
23143 || (size_t) (inote.descdata - inote.namedata) > data_remaining
23144 || (size_t) (next - inote.descdata) < inote.descsz
23145 || ((size_t) (next - inote.descdata)
23146 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
23148 warn (_("note with invalid namesz and/or descsz found at offset %#tx\n"),
23149 (char *) external - (char *) pnotes);
23150 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx, alignment: %u\n"),
23151 inote.type, inote.namesz, inote.descsz, (int) align);
23152 break;
23155 external = (Elf_External_Note *) next;
23157 /* Verify that name is null terminated. It appears that at least
23158 one version of Linux (RedHat 6.0) generates corefiles that don't
23159 comply with the ELF spec by failing to include the null byte in
23160 namesz. */
23161 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
23163 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
23165 temp = (char *) malloc (inote.namesz + 1);
23166 if (temp == NULL)
23168 error (_("Out of memory allocating space for inote name\n"));
23169 res = false;
23170 break;
23173 memcpy (temp, inote.namedata, inote.namesz);
23174 inote.namedata = temp;
23176 inote.namedata[inote.namesz] = 0;
23179 if (! process_note (& inote, filedata))
23180 res = false;
23182 free (temp);
23183 temp = NULL;
23186 free (pnotes);
23188 return res;
23191 static bool
23192 process_corefile_note_segments (Filedata * filedata)
23194 Elf_Internal_Phdr *segment;
23195 unsigned int i;
23196 bool res = true;
23198 if (! get_program_headers (filedata))
23199 return true;
23201 for (i = 0, segment = filedata->program_headers;
23202 i < filedata->file_header.e_phnum;
23203 i++, segment++)
23205 if (segment->p_type == PT_NOTE)
23206 if (! process_notes_at (filedata, NULL, segment->p_offset,
23207 segment->p_filesz, segment->p_align))
23208 res = false;
23211 return res;
23214 static bool
23215 process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
23217 Elf_External_Note * pnotes;
23218 Elf_External_Note * external;
23219 char * end;
23220 bool res = true;
23222 if (length <= 0)
23223 return false;
23225 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
23226 _("v850 notes"));
23227 if (pnotes == NULL)
23228 return false;
23230 external = pnotes;
23231 end = (char*) pnotes + length;
23233 printf (_("\nDisplaying contents of Renesas V850 notes section at offset"
23234 " %#" PRIx64 " with length %#" PRIx64 ":\n"),
23235 offset, length);
23237 while ((char *) external + sizeof (Elf_External_Note) < end)
23239 Elf_External_Note * next;
23240 Elf_Internal_Note inote;
23242 inote.type = BYTE_GET (external->type);
23243 inote.namesz = BYTE_GET (external->namesz);
23244 inote.namedata = external->name;
23245 inote.descsz = BYTE_GET (external->descsz);
23246 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
23247 inote.descpos = offset + (inote.descdata - (char *) pnotes);
23249 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
23251 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
23252 inote.descdata = inote.namedata;
23253 inote.namesz = 0;
23256 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
23258 if ( ((char *) next > end)
23259 || ((char *) next < (char *) pnotes))
23261 warn (_("corrupt descsz found in note at offset %#tx\n"),
23262 (char *) external - (char *) pnotes);
23263 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
23264 inote.type, inote.namesz, inote.descsz);
23265 break;
23268 external = next;
23270 /* Prevent out-of-bounds indexing. */
23271 if ( inote.namedata + inote.namesz > end
23272 || inote.namedata + inote.namesz < inote.namedata)
23274 warn (_("corrupt namesz found in note at offset %#zx\n"),
23275 (char *) external - (char *) pnotes);
23276 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
23277 inote.type, inote.namesz, inote.descsz);
23278 break;
23281 printf (" %s: ", get_v850_elf_note_type (inote.type));
23283 if (! print_v850_note (& inote))
23285 res = false;
23286 printf ("<corrupt sizes: namesz: %#lx, descsz: %#lx>\n",
23287 inote.namesz, inote.descsz);
23291 free (pnotes);
23293 return res;
23296 static bool
23297 process_note_sections (Filedata * filedata)
23299 Elf_Internal_Shdr *section;
23300 size_t i;
23301 unsigned int n = 0;
23302 bool res = true;
23304 for (i = 0, section = filedata->section_headers;
23305 i < filedata->file_header.e_shnum && section != NULL;
23306 i++, section++)
23308 if (section->sh_type == SHT_NOTE)
23310 if (! process_notes_at (filedata, section, section->sh_offset,
23311 section->sh_size, section->sh_addralign))
23312 res = false;
23313 n++;
23316 if (( filedata->file_header.e_machine == EM_V800
23317 || filedata->file_header.e_machine == EM_V850
23318 || filedata->file_header.e_machine == EM_CYGNUS_V850)
23319 && section->sh_type == SHT_RENESAS_INFO)
23321 if (! process_v850_notes (filedata, section->sh_offset,
23322 section->sh_size))
23323 res = false;
23324 n++;
23328 if (n == 0)
23329 /* Try processing NOTE segments instead. */
23330 return process_corefile_note_segments (filedata);
23332 return res;
23335 static bool
23336 process_notes (Filedata * filedata)
23338 /* If we have not been asked to display the notes then do nothing. */
23339 if (! do_notes)
23340 return true;
23342 if (filedata->file_header.e_type != ET_CORE)
23343 return process_note_sections (filedata);
23345 /* No program headers means no NOTE segment. */
23346 if (filedata->file_header.e_phnum > 0)
23347 return process_corefile_note_segments (filedata);
23349 if (filedata->is_separate)
23350 printf (_("No notes found in linked file '%s'.\n"),
23351 filedata->file_name);
23352 else
23353 printf (_("No notes found file.\n"));
23355 return true;
23358 static unsigned char *
23359 display_public_gnu_attributes (unsigned char * start,
23360 const unsigned char * const end)
23362 printf (_(" Unknown GNU attribute: %s\n"), start);
23364 start += strnlen ((char *) start, end - start);
23365 display_raw_attribute (start, end);
23367 return (unsigned char *) end;
23370 static unsigned char *
23371 display_generic_attribute (unsigned char * start,
23372 unsigned int tag,
23373 const unsigned char * const end)
23375 if (tag == 0)
23376 return (unsigned char *) end;
23378 return display_tag_value (tag, start, end);
23381 static bool
23382 process_arch_specific (Filedata * filedata)
23384 if (! do_arch)
23385 return true;
23387 switch (filedata->file_header.e_machine)
23389 case EM_ARC:
23390 case EM_ARC_COMPACT:
23391 case EM_ARC_COMPACT2:
23392 case EM_ARC_COMPACT3:
23393 case EM_ARC_COMPACT3_64:
23394 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
23395 display_arc_attribute,
23396 display_generic_attribute);
23397 case EM_ARM:
23398 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
23399 display_arm_attribute,
23400 display_generic_attribute);
23402 case EM_MIPS:
23403 case EM_MIPS_RS3_LE:
23404 return process_mips_specific (filedata);
23406 case EM_MSP430:
23407 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
23408 display_msp430_attribute,
23409 display_msp430_gnu_attribute);
23411 case EM_RISCV:
23412 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
23413 display_riscv_attribute,
23414 display_generic_attribute);
23416 case EM_NDS32:
23417 return process_nds32_specific (filedata);
23419 case EM_68K:
23420 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
23421 display_m68k_gnu_attribute);
23423 case EM_PPC:
23424 case EM_PPC64:
23425 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
23426 display_power_gnu_attribute);
23428 case EM_S390:
23429 case EM_S390_OLD:
23430 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
23431 display_s390_gnu_attribute);
23433 case EM_SPARC:
23434 case EM_SPARC32PLUS:
23435 case EM_SPARCV9:
23436 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
23437 display_sparc_gnu_attribute);
23439 case EM_TI_C6000:
23440 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
23441 display_tic6x_attribute,
23442 display_generic_attribute);
23444 case EM_CSKY:
23445 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
23446 display_csky_attribute, NULL);
23448 default:
23449 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
23450 display_public_gnu_attributes,
23451 display_generic_attribute);
23455 static bool
23456 get_file_header (Filedata * filedata)
23458 /* Read in the identity array. */
23459 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
23460 return false;
23462 /* Determine how to read the rest of the header. */
23463 switch (filedata->file_header.e_ident[EI_DATA])
23465 default:
23466 case ELFDATANONE:
23467 case ELFDATA2LSB:
23468 byte_get = byte_get_little_endian;
23469 byte_put = byte_put_little_endian;
23470 break;
23471 case ELFDATA2MSB:
23472 byte_get = byte_get_big_endian;
23473 byte_put = byte_put_big_endian;
23474 break;
23477 /* For now we only support 32 bit and 64 bit ELF files. */
23478 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
23480 /* Read in the rest of the header. */
23481 if (is_32bit_elf)
23483 Elf32_External_Ehdr ehdr32;
23485 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
23486 return false;
23488 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
23489 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
23490 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
23491 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
23492 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
23493 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
23494 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
23495 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
23496 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
23497 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
23498 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
23499 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
23500 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
23502 else
23504 Elf64_External_Ehdr ehdr64;
23506 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
23507 return false;
23509 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
23510 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
23511 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
23512 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
23513 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
23514 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
23515 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
23516 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
23517 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
23518 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
23519 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
23520 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
23521 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
23524 return true;
23527 static void
23528 free_filedata (Filedata *filedata)
23530 free (filedata->program_interpreter);
23531 free (filedata->program_headers);
23532 free (filedata->section_headers);
23533 free (filedata->string_table);
23534 free (filedata->dump.dump_sects);
23535 free (filedata->dynamic_strings);
23536 free (filedata->dynamic_symbols);
23537 free (filedata->dynamic_syminfo);
23538 free (filedata->dynamic_section);
23540 while (filedata->symtab_shndx_list != NULL)
23542 elf_section_list *next = filedata->symtab_shndx_list->next;
23543 free (filedata->symtab_shndx_list);
23544 filedata->symtab_shndx_list = next;
23547 free (filedata->section_headers_groups);
23549 if (filedata->section_groups)
23551 size_t i;
23552 struct group_list * g;
23553 struct group_list * next;
23555 for (i = 0; i < filedata->group_count; i++)
23557 for (g = filedata->section_groups [i].root; g != NULL; g = next)
23559 next = g->next;
23560 free (g);
23564 free (filedata->section_groups);
23566 memset (&filedata->section_headers, 0,
23567 sizeof (Filedata) - offsetof (Filedata, section_headers));
23570 static void
23571 close_file (Filedata * filedata)
23573 if (filedata)
23575 if (filedata->handle)
23576 fclose (filedata->handle);
23577 free (filedata);
23581 void
23582 close_debug_file (void * data)
23584 free_filedata ((Filedata *) data);
23585 close_file ((Filedata *) data);
23588 static Filedata *
23589 open_file (const char * pathname, bool is_separate)
23591 struct stat statbuf;
23592 Filedata * filedata = NULL;
23594 if (stat (pathname, & statbuf) < 0
23595 || ! S_ISREG (statbuf.st_mode))
23596 goto fail;
23598 filedata = calloc (1, sizeof * filedata);
23599 if (filedata == NULL)
23600 goto fail;
23602 filedata->handle = fopen (pathname, "rb");
23603 if (filedata->handle == NULL)
23604 goto fail;
23606 filedata->file_size = statbuf.st_size;
23607 filedata->file_name = pathname;
23608 filedata->is_separate = is_separate;
23610 if (! get_file_header (filedata))
23611 goto fail;
23613 if (!get_section_headers (filedata, false))
23614 goto fail;
23616 return filedata;
23618 fail:
23619 if (filedata)
23621 if (filedata->handle)
23622 fclose (filedata->handle);
23623 free (filedata);
23625 return NULL;
23628 void *
23629 open_debug_file (const char * pathname)
23631 return open_file (pathname, true);
23634 static void
23635 initialise_dump_sects (Filedata * filedata)
23637 /* Initialise the dump_sects array from the cmdline_dump_sects array.
23638 Note we do this even if cmdline_dump_sects is empty because we
23639 must make sure that the dump_sets array is zeroed out before each
23640 object file is processed. */
23641 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
23642 memset (filedata->dump.dump_sects, 0,
23643 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
23645 if (cmdline.num_dump_sects > 0)
23647 if (filedata->dump.num_dump_sects == 0)
23648 /* A sneaky way of allocating the dump_sects array. */
23649 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
23651 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
23652 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
23653 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
23657 static bool
23658 might_need_separate_debug_info (Filedata * filedata)
23660 /* Debuginfo files do not need further separate file loading. */
23661 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
23662 return false;
23664 /* Since do_follow_links might be enabled by default, only treat it as an
23665 indication that separate files should be loaded if setting it was a
23666 deliberate user action. */
23667 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
23668 return true;
23670 if (process_links || do_syms || do_unwind
23671 || dump_any_debugging || do_dump || do_debugging)
23672 return true;
23674 return false;
23677 /* Process one ELF object file according to the command line options.
23678 This file may actually be stored in an archive. The file is
23679 positioned at the start of the ELF object. Returns TRUE if no
23680 problems were encountered, FALSE otherwise. */
23682 static bool
23683 process_object (Filedata * filedata)
23685 bool have_separate_files;
23686 unsigned int i;
23687 bool res;
23689 if (! get_file_header (filedata))
23691 error (_("%s: Failed to read file header\n"), filedata->file_name);
23692 return false;
23695 /* Initialise per file variables. */
23696 for (i = ARRAY_SIZE (filedata->version_info); i--;)
23697 filedata->version_info[i] = 0;
23699 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
23700 filedata->dynamic_info[i] = 0;
23701 filedata->dynamic_info_DT_GNU_HASH = 0;
23702 filedata->dynamic_info_DT_MIPS_XHASH = 0;
23704 /* Process the file. */
23705 if (show_name)
23706 printf (_("\nFile: %s\n"), filedata->file_name);
23708 initialise_dump_sects (filedata);
23710 /* There may be some extensions in the first section header. Don't
23711 bomb if we can't read it. */
23712 get_section_headers (filedata, true);
23714 if (! process_file_header (filedata))
23716 res = false;
23717 goto out;
23720 /* Throw away the single section header read above, so that we
23721 re-read the entire set. */
23722 free (filedata->section_headers);
23723 filedata->section_headers = NULL;
23725 if (! process_section_headers (filedata))
23727 /* Without loaded section headers we cannot process lots of things. */
23728 do_unwind = do_version = do_dump = do_arch = false;
23730 if (! do_using_dynamic)
23731 do_syms = do_dyn_syms = do_reloc = false;
23734 if (! process_section_groups (filedata))
23735 /* Without loaded section groups we cannot process unwind. */
23736 do_unwind = false;
23738 process_program_headers (filedata);
23740 res = process_dynamic_section (filedata);
23742 if (! process_relocs (filedata))
23743 res = false;
23745 if (! process_unwind (filedata))
23746 res = false;
23748 if (! process_symbol_table (filedata))
23749 res = false;
23751 if (! process_lto_symbol_tables (filedata))
23752 res = false;
23754 if (! process_syminfo (filedata))
23755 res = false;
23757 if (! process_version_sections (filedata))
23758 res = false;
23760 if (might_need_separate_debug_info (filedata))
23761 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
23762 else
23763 have_separate_files = false;
23765 if (! process_section_contents (filedata))
23766 res = false;
23768 if (have_separate_files)
23770 separate_info * d;
23772 for (d = first_separate_info; d != NULL; d = d->next)
23774 initialise_dump_sects (d->handle);
23776 if (process_links && ! process_file_header (d->handle))
23777 res = false;
23778 else if (! process_section_headers (d->handle))
23779 res = false;
23780 else if (! process_section_contents (d->handle))
23781 res = false;
23782 else if (process_links)
23784 if (! process_section_groups (d->handle))
23785 res = false;
23786 process_program_headers (d->handle);
23787 if (! process_dynamic_section (d->handle))
23788 res = false;
23789 if (! process_relocs (d->handle))
23790 res = false;
23791 if (! process_unwind (d->handle))
23792 res = false;
23793 if (! process_symbol_table (d->handle))
23794 res = false;
23795 if (! process_lto_symbol_tables (d->handle))
23796 res = false;
23797 if (! process_syminfo (d->handle))
23798 res = false;
23799 if (! process_version_sections (d->handle))
23800 res = false;
23801 if (! process_notes (d->handle))
23802 res = false;
23806 /* The file handles are closed by the call to free_debug_memory() below. */
23809 if (! process_notes (filedata))
23810 res = false;
23812 if (! process_gnu_liblist (filedata))
23813 res = false;
23815 if (! process_arch_specific (filedata))
23816 res = false;
23818 out:
23819 free_filedata (filedata);
23821 free_debug_memory ();
23823 return res;
23826 /* Process an ELF archive.
23827 On entry the file is positioned just after the ARMAG string.
23828 Returns TRUE upon success, FALSE otherwise. */
23830 static bool
23831 process_archive (Filedata * filedata, bool is_thin_archive)
23833 struct archive_info arch;
23834 struct archive_info nested_arch;
23835 size_t got;
23836 bool ret = true;
23838 show_name = true;
23840 /* The ARCH structure is used to hold information about this archive. */
23841 arch.file_name = NULL;
23842 arch.file = NULL;
23843 arch.index_array = NULL;
23844 arch.sym_table = NULL;
23845 arch.longnames = NULL;
23847 /* The NESTED_ARCH structure is used as a single-item cache of information
23848 about a nested archive (when members of a thin archive reside within
23849 another regular archive file). */
23850 nested_arch.file_name = NULL;
23851 nested_arch.file = NULL;
23852 nested_arch.index_array = NULL;
23853 nested_arch.sym_table = NULL;
23854 nested_arch.longnames = NULL;
23856 if (setup_archive (&arch, filedata->file_name, filedata->handle,
23857 filedata->file_size, is_thin_archive,
23858 do_archive_index) != 0)
23860 ret = false;
23861 goto out;
23864 if (do_archive_index)
23866 if (arch.sym_table == NULL)
23867 error (_("%s: unable to dump the index as none was found\n"),
23868 filedata->file_name);
23869 else
23871 uint64_t i, l;
23872 uint64_t current_pos;
23874 printf (_("Index of archive %s: (%" PRIu64 " entries,"
23875 " %#" PRIx64 " bytes in the symbol table)\n"),
23876 filedata->file_name, arch.index_num,
23877 arch.sym_size);
23879 current_pos = ftell (filedata->handle);
23881 for (i = l = 0; i < arch.index_num; i++)
23883 if (i == 0
23884 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
23886 char * member_name
23887 = get_archive_member_name_at (&arch, arch.index_array[i],
23888 &nested_arch);
23890 if (member_name != NULL)
23892 char * qualified_name
23893 = make_qualified_name (&arch, &nested_arch,
23894 member_name);
23896 if (qualified_name != NULL)
23898 printf (_("Contents of binary %s at offset "),
23899 qualified_name);
23900 (void) print_vma (arch.index_array[i], PREFIX_HEX);
23901 putchar ('\n');
23902 free (qualified_name);
23904 free (member_name);
23908 if (l >= arch.sym_size)
23910 error (_("%s: end of the symbol table reached "
23911 "before the end of the index\n"),
23912 filedata->file_name);
23913 ret = false;
23914 break;
23916 /* PR 17531: file: 0b6630b2. */
23917 printf ("\t%.*s\n",
23918 (int) (arch.sym_size - l), arch.sym_table + l);
23919 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
23922 if (arch.uses_64bit_indices)
23923 l = (l + 7) & ~ 7;
23924 else
23925 l += l & 1;
23927 if (l < arch.sym_size)
23929 error (ngettext ("%s: %" PRId64 " byte remains in the symbol table, "
23930 "but without corresponding entries in "
23931 "the index table\n",
23932 "%s: %" PRId64 " bytes remain in the symbol table, "
23933 "but without corresponding entries in "
23934 "the index table\n",
23935 arch.sym_size - l),
23936 filedata->file_name, arch.sym_size - l);
23937 ret = false;
23940 if (fseek64 (filedata->handle, current_pos, SEEK_SET) != 0)
23942 error (_("%s: failed to seek back to start of object files "
23943 "in the archive\n"),
23944 filedata->file_name);
23945 ret = false;
23946 goto out;
23950 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
23951 && !do_segments && !do_header && !do_dump && !do_version
23952 && !do_histogram && !do_debugging && !do_arch && !do_notes
23953 && !do_section_groups && !do_dyn_syms)
23955 ret = true; /* Archive index only. */
23956 goto out;
23960 while (1)
23962 char * name;
23963 size_t namelen;
23964 char * qualified_name;
23966 /* Read the next archive header. */
23967 if (fseek64 (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
23969 error (_("%s: failed to seek to next archive header\n"),
23970 arch.file_name);
23971 ret = false;
23972 break;
23974 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
23975 if (got != sizeof arch.arhdr)
23977 if (got == 0)
23978 break;
23979 /* PR 24049 - we cannot use filedata->file_name as this will
23980 have already been freed. */
23981 error (_("%s: failed to read archive header\n"), arch.file_name);
23983 ret = false;
23984 break;
23986 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
23988 error (_("%s: did not find a valid archive header\n"),
23989 arch.file_name);
23990 ret = false;
23991 break;
23994 arch.next_arhdr_offset += sizeof arch.arhdr;
23996 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
23998 name = get_archive_member_name (&arch, &nested_arch);
23999 if (name == NULL)
24001 error (_("%s: bad archive file name\n"), arch.file_name);
24002 ret = false;
24003 break;
24005 namelen = strlen (name);
24007 qualified_name = make_qualified_name (&arch, &nested_arch, name);
24008 if (qualified_name == NULL)
24010 error (_("%s: bad archive file name\n"), arch.file_name);
24011 free (name);
24012 ret = false;
24013 break;
24016 if (is_thin_archive && arch.nested_member_origin == 0)
24018 /* This is a proxy for an external member of a thin archive. */
24019 Filedata * member_filedata;
24020 char * member_file_name = adjust_relative_path
24021 (filedata->file_name, name, namelen);
24023 free (name);
24024 if (member_file_name == NULL)
24026 free (qualified_name);
24027 ret = false;
24028 break;
24031 member_filedata = open_file (member_file_name, false);
24032 if (member_filedata == NULL)
24034 error (_("Input file '%s' is not readable.\n"), member_file_name);
24035 free (member_file_name);
24036 free (qualified_name);
24037 ret = false;
24038 break;
24041 filedata->archive_file_offset = arch.nested_member_origin;
24042 member_filedata->file_name = qualified_name;
24044 /* The call to process_object() expects the file to be at the beginning. */
24045 rewind (member_filedata->handle);
24047 if (! process_object (member_filedata))
24048 ret = false;
24050 close_file (member_filedata);
24051 free (member_file_name);
24053 else if (is_thin_archive)
24055 Filedata thin_filedata;
24057 memset (&thin_filedata, 0, sizeof (thin_filedata));
24059 /* PR 15140: Allow for corrupt thin archives. */
24060 if (nested_arch.file == NULL)
24062 error (_("%s: contains corrupt thin archive: %s\n"),
24063 qualified_name, name);
24064 free (qualified_name);
24065 free (name);
24066 ret = false;
24067 break;
24069 free (name);
24071 /* This is a proxy for a member of a nested archive. */
24072 filedata->archive_file_offset
24073 = arch.nested_member_origin + sizeof arch.arhdr;
24075 /* The nested archive file will have been opened and setup by
24076 get_archive_member_name. */
24077 if (fseek64 (nested_arch.file, filedata->archive_file_offset,
24078 SEEK_SET) != 0)
24080 error (_("%s: failed to seek to archive member.\n"),
24081 nested_arch.file_name);
24082 free (qualified_name);
24083 ret = false;
24084 break;
24087 thin_filedata.handle = nested_arch.file;
24088 thin_filedata.file_name = qualified_name;
24090 if (! process_object (& thin_filedata))
24091 ret = false;
24093 else
24095 free (name);
24096 filedata->archive_file_offset = arch.next_arhdr_offset;
24097 filedata->file_name = qualified_name;
24098 if (! process_object (filedata))
24099 ret = false;
24100 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
24101 /* Stop looping with "negative" archive_file_size. */
24102 if (arch.next_arhdr_offset < filedata->archive_file_size)
24103 arch.next_arhdr_offset = -1ul;
24106 free (qualified_name);
24109 out:
24110 if (nested_arch.file != NULL)
24111 fclose (nested_arch.file);
24112 release_archive (&nested_arch);
24113 release_archive (&arch);
24115 return ret;
24118 static bool
24119 process_file (char * file_name)
24121 Filedata * filedata = NULL;
24122 struct stat statbuf;
24123 char armag[SARMAG];
24124 bool ret = true;
24126 if (stat (file_name, &statbuf) < 0)
24128 if (errno == ENOENT)
24129 error (_("'%s': No such file\n"), file_name);
24130 else
24131 error (_("Could not locate '%s'. System error message: %s\n"),
24132 file_name, strerror (errno));
24133 return false;
24136 if (! S_ISREG (statbuf.st_mode))
24138 error (_("'%s' is not an ordinary file\n"), file_name);
24139 return false;
24142 filedata = calloc (1, sizeof * filedata);
24143 if (filedata == NULL)
24145 error (_("Out of memory allocating file data structure\n"));
24146 return false;
24149 filedata->file_name = file_name;
24150 filedata->handle = fopen (file_name, "rb");
24151 if (filedata->handle == NULL)
24153 error (_("Input file '%s' is not readable.\n"), file_name);
24154 free (filedata);
24155 return false;
24158 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
24160 error (_("%s: Failed to read file's magic number\n"), file_name);
24161 fclose (filedata->handle);
24162 free (filedata);
24163 return false;
24166 filedata->file_size = statbuf.st_size;
24167 filedata->is_separate = false;
24169 if (memcmp (armag, ARMAG, SARMAG) == 0)
24171 if (! process_archive (filedata, false))
24172 ret = false;
24174 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
24176 if ( ! process_archive (filedata, true))
24177 ret = false;
24179 else
24181 if (do_archive_index && !check_all)
24182 error (_("File %s is not an archive so its index cannot be displayed.\n"),
24183 file_name);
24185 rewind (filedata->handle);
24186 filedata->archive_file_size = filedata->archive_file_offset = 0;
24188 if (! process_object (filedata))
24189 ret = false;
24192 fclose (filedata->handle);
24193 free (filedata->section_headers);
24194 free (filedata->program_headers);
24195 free (filedata->string_table);
24196 free (filedata->dump.dump_sects);
24197 free (filedata);
24199 free (ba_cache.strtab);
24200 ba_cache.strtab = NULL;
24201 free (ba_cache.symtab);
24202 ba_cache.symtab = NULL;
24203 ba_cache.filedata = NULL;
24205 return ret;
24208 #ifdef SUPPORT_DISASSEMBLY
24209 /* Needed by the i386 disassembler. For extra credit, someone could
24210 fix this so that we insert symbolic addresses here, esp for GOT/PLT
24211 symbols. */
24213 void
24214 print_address (unsigned int addr, FILE * outfile)
24216 fprintf (outfile,"0x%8.8x", addr);
24219 /* Needed by the i386 disassembler. */
24221 void
24222 db_task_printsym (unsigned int addr)
24224 print_address (addr, stderr);
24226 #endif
24229 main (int argc, char ** argv)
24231 int err;
24233 #ifdef HAVE_LC_MESSAGES
24234 setlocale (LC_MESSAGES, "");
24235 #endif
24236 setlocale (LC_CTYPE, "");
24237 bindtextdomain (PACKAGE, LOCALEDIR);
24238 textdomain (PACKAGE);
24240 expandargv (&argc, &argv);
24242 parse_args (& cmdline, argc, argv);
24244 if (optind < (argc - 1))
24245 /* When displaying information for more than one file,
24246 prefix the information with the file name. */
24247 show_name = true;
24248 else if (optind >= argc)
24250 /* Ensure that the warning is always displayed. */
24251 do_checks = true;
24253 warn (_("Nothing to do.\n"));
24254 usage (stderr);
24257 err = false;
24258 while (optind < argc)
24259 if (! process_file (argv[optind++]))
24260 err = true;
24262 free (cmdline.dump_sects);
24264 free (dump_ctf_symtab_name);
24265 free (dump_ctf_strtab_name);
24266 free (dump_ctf_parent_name);
24268 return err ? EXIT_FAILURE : EXIT_SUCCESS;