Fix RELOC_FOR_GLOBAL_SYMBOLS macro so that it can cope with user defined symbols...
[binutils-gdb.git] / binutils / readelf.c
blobf8305b4715b8243bb3889e11492daef59e26acdc
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 (Elf_Internal_Sym * symtab,
1540 uint64_t nsyms,
1541 char * strtab,
1542 uint64_t strtablen,
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 /* Paranoia. */
1552 if (symtab == NULL || nsyms == 0 || strtab == NULL || strtablen == 0)
1553 return NULL;
1555 /* FIXME: Since this function is likely to be called repeatedly with
1556 slightly increasing addresses each time, we could speed things up by
1557 caching the last returned value and starting our search from there. */
1558 while (beg < end)
1560 Elf_Internal_Sym * sym;
1561 uint64_t value;
1563 sym = beg + (end - beg) / 2;
1565 value = sym->st_value;
1567 if (sym->st_name != 0
1568 && where >= value
1569 && where - value < dist)
1571 best = sym;
1572 dist = where - value;
1573 if (dist == 0)
1574 break;
1577 if (where < value)
1578 end = sym;
1579 else
1580 beg = sym + 1;
1583 if (best == NULL)
1584 return NULL;
1586 if (best->st_name >= strtablen)
1587 return NULL;
1589 if (offset_return != NULL)
1590 * offset_return = dist;
1592 return strtab + best->st_name;
1595 static void
1596 print_relr_addr_and_sym (Elf_Internal_Sym * symtab,
1597 uint64_t nsyms,
1598 char * strtab,
1599 uint64_t strtablen,
1600 uint64_t where)
1602 const char * symname = NULL;
1603 uint64_t offset = 0;
1605 print_vma (where, ZERO_HEX);
1606 printf (" ");
1608 symname = get_symbol_at (symtab, nsyms, strtab, strtablen, where, & offset);
1610 if (symname == NULL)
1611 printf ("<no sym>");
1612 else if (offset == 0)
1613 print_symbol_name (38, symname);
1614 else
1616 print_symbol_name (28, symname);
1617 printf (" + ");
1618 print_vma (offset, PREFIX_HEX);
1622 static /* signed */ int
1623 symcmp (const void *p, const void *q)
1625 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
1626 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
1628 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
1631 static uint64_t
1632 count_relr_relocations (Filedata * filedata,
1633 Elf_Internal_Shdr * section)
1635 uint64_t * relrs;
1636 uint64_t nentries;
1637 uint64_t i;
1638 uint64_t count;
1639 int entsize;
1641 if (section == NULL
1642 || section->sh_type != SHT_RELR
1643 || section->sh_size == 0)
1644 return 0;
1646 entsize = section->sh_entsize;
1647 if (entsize == 0)
1648 entsize = is_32bit_elf
1649 ? sizeof (Elf32_External_Relr) : sizeof (Elf64_External_Relr);
1650 else if (entsize != sizeof (Elf32_External_Relr)
1651 && entsize != sizeof (Elf64_External_Relr))
1652 return 0;
1654 nentries = section->sh_size / entsize;
1655 if (nentries == 0)
1656 return 0;
1658 /* FIXME: This call to get_data duplicates one that follows in
1659 dump_relr_relocations(). They could be combined into just
1660 one call. */
1661 relrs = get_data (NULL, filedata, section->sh_offset, 1,
1662 section->sh_size, _("RELR relocation data"));
1663 if (relrs == NULL)
1664 return 0;
1666 for (count = i = 0; i < nentries; i++)
1668 uint64_t entry;
1670 if (entsize == sizeof (Elf32_External_Relr))
1671 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1672 else
1673 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1675 if ((entry & 1) == 0)
1677 ++ count;
1679 else
1681 if (entry == 1)
1682 continue;
1684 for (; entry >>= 1;)
1685 if ((entry & 1) == 1)
1686 ++ count;
1690 free (relrs);
1691 return count;
1694 static bool
1695 dump_relr_relocations (Filedata * filedata,
1696 Elf_Internal_Shdr * section,
1697 Elf_Internal_Sym * symtab,
1698 uint64_t nsyms,
1699 char * strtab,
1700 uint64_t strtablen)
1702 uint64_t * relrs;
1703 uint64_t nentries, i;
1704 uint64_t relr_size = section->sh_size;
1705 int relr_entsize = section->sh_entsize;
1706 uint64_t relr_offset = section->sh_offset;
1707 uint64_t where = 0;
1708 int num_bits_in_entry;
1710 if (relr_entsize == 0)
1711 relr_entsize = is_32bit_elf
1712 ? sizeof (Elf32_External_Relr) : sizeof (Elf64_External_Relr);
1714 nentries = relr_size / relr_entsize;
1716 if (nentries == 0)
1717 return true;
1719 if (relr_entsize == sizeof (Elf32_External_Relr))
1720 num_bits_in_entry = 31;
1721 else if (relr_entsize == sizeof (Elf64_External_Relr))
1722 num_bits_in_entry = 63;
1723 else
1725 warn (_("Unexpected entsize for RELR section\n"));
1726 return false;
1729 relrs = get_data (NULL, filedata, relr_offset, 1, relr_size, _("RELR relocation data"));
1730 if (relrs == NULL)
1731 return false;
1733 if (symtab != NULL)
1735 /* Symbol tables are not sorted on address, but we want a quick lookup
1736 for the symbol associated with each address computed below, so sort
1737 the table now. FIXME: This assumes that the symbol table will not
1738 be used later on for some other purpose. */
1739 qsort (symtab, nsyms, sizeof (Elf_Internal_Sym), symcmp);
1742 if (relr_entsize == sizeof (Elf32_External_Relr))
1743 printf (_ ("Index: Entry Address Symbolic Address\n"));
1744 else
1745 printf (_ ("Index: Entry Address Symbolic Address\n"));
1747 for (i = 0; i < nentries; i++)
1749 uint64_t entry;
1751 if (relr_entsize == sizeof (Elf32_External_Relr))
1752 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1753 else
1754 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1756 /* We assume that there will never be more than 9999 entries. */
1757 printf (_("%04u: "), (unsigned int) i);
1758 print_vma (entry, ZERO_HEX);
1759 printf (" ");
1761 if ((entry & 1) == 0)
1763 where = entry;
1764 print_relr_addr_and_sym (symtab, nsyms, strtab, strtablen, where);
1765 printf ("\n");
1766 where += relr_entsize;
1768 else
1770 bool first = true;
1771 int j;
1773 /* The least significant bit is ignored. */
1774 if (entry == 1)
1775 /* This can actually happen when the linker is allowed to shrink
1776 RELR sections. For more details see: https://reviews.llvm.org/D67164. */
1777 continue;
1778 else if (i == 0)
1779 warn (_("Unusual RELR bitmap - no previous entry to set the base address\n"));
1781 for (j = 0; entry >>= 1; j++)
1782 if ((entry & 1) == 1)
1784 uint64_t addr = where + (j * relr_entsize);
1786 if (first)
1788 print_relr_addr_and_sym (symtab, nsyms, strtab, strtablen, addr);
1789 first = false;
1791 else
1793 printf (_("\n%*s "), relr_entsize == 4 ? 15 : 23, " ");
1794 print_relr_addr_and_sym (symtab, nsyms, strtab, strtablen, addr);
1798 printf ("\n");
1799 where += num_bits_in_entry * relr_entsize;
1803 free (relrs);
1804 return true;
1807 /* Display the contents of the relocation data found at the specified
1808 offset. */
1810 static bool
1811 dump_relocations (Filedata * filedata,
1812 uint64_t rel_offset,
1813 uint64_t rel_size,
1814 Elf_Internal_Sym * symtab,
1815 uint64_t nsyms,
1816 char * strtab,
1817 uint64_t strtablen,
1818 relocation_type rel_type,
1819 bool is_dynsym)
1821 size_t i;
1822 Elf_Internal_Rela * rels;
1823 bool res = true;
1825 if (rel_type == reltype_unknown)
1826 rel_type = guess_is_rela (filedata->file_header.e_machine) ? reltype_rela : reltype_rel;
1828 if (rel_type == reltype_rela)
1830 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
1831 return false;
1833 else if (rel_type == reltype_rel)
1835 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
1836 return false;
1838 else if (rel_type == reltype_relr)
1840 /* This should have been handled by display_relocations(). */
1841 return false;
1844 if (is_32bit_elf)
1846 if (rel_type == reltype_rela)
1848 if (do_wide)
1849 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1850 else
1851 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1853 else
1855 if (do_wide)
1856 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1857 else
1858 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1861 else
1863 if (rel_type == reltype_rela)
1865 if (do_wide)
1866 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
1867 else
1868 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1870 else
1872 if (do_wide)
1873 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
1874 else
1875 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1879 for (i = 0; i < rel_size; i++)
1881 const char * rtype;
1882 uint64_t offset;
1883 uint64_t inf;
1884 uint64_t symtab_index;
1885 uint64_t type;
1887 offset = rels[i].r_offset;
1888 inf = rels[i].r_info;
1890 type = get_reloc_type (filedata, inf);
1891 symtab_index = get_reloc_symindex (inf);
1893 if (is_32bit_elf)
1895 printf ("%8.8lx %8.8lx ",
1896 (unsigned long) offset & 0xffffffff,
1897 (unsigned long) inf & 0xffffffff);
1899 else
1901 printf (do_wide
1902 ? "%16.16" PRIx64 " %16.16" PRIx64 " "
1903 : "%12.12" PRIx64 " %12.12" PRIx64 " ",
1904 offset, inf);
1907 switch (filedata->file_header.e_machine)
1909 default:
1910 rtype = NULL;
1911 break;
1913 case EM_AARCH64:
1914 rtype = elf_aarch64_reloc_type (type);
1915 break;
1917 case EM_M32R:
1918 case EM_CYGNUS_M32R:
1919 rtype = elf_m32r_reloc_type (type);
1920 break;
1922 case EM_386:
1923 case EM_IAMCU:
1924 rtype = elf_i386_reloc_type (type);
1925 break;
1927 case EM_68HC11:
1928 case EM_68HC12:
1929 rtype = elf_m68hc11_reloc_type (type);
1930 break;
1932 case EM_S12Z:
1933 rtype = elf_s12z_reloc_type (type);
1934 break;
1936 case EM_68K:
1937 rtype = elf_m68k_reloc_type (type);
1938 break;
1940 case EM_960:
1941 rtype = elf_i960_reloc_type (type);
1942 break;
1944 case EM_AVR:
1945 case EM_AVR_OLD:
1946 rtype = elf_avr_reloc_type (type);
1947 break;
1949 case EM_OLD_SPARCV9:
1950 case EM_SPARC32PLUS:
1951 case EM_SPARCV9:
1952 case EM_SPARC:
1953 rtype = elf_sparc_reloc_type (type);
1954 break;
1956 case EM_SPU:
1957 rtype = elf_spu_reloc_type (type);
1958 break;
1960 case EM_V800:
1961 rtype = v800_reloc_type (type);
1962 break;
1963 case EM_V850:
1964 case EM_CYGNUS_V850:
1965 rtype = v850_reloc_type (type);
1966 break;
1968 case EM_D10V:
1969 case EM_CYGNUS_D10V:
1970 rtype = elf_d10v_reloc_type (type);
1971 break;
1973 case EM_D30V:
1974 case EM_CYGNUS_D30V:
1975 rtype = elf_d30v_reloc_type (type);
1976 break;
1978 case EM_DLX:
1979 rtype = elf_dlx_reloc_type (type);
1980 break;
1982 case EM_SH:
1983 rtype = elf_sh_reloc_type (type);
1984 break;
1986 case EM_MN10300:
1987 case EM_CYGNUS_MN10300:
1988 rtype = elf_mn10300_reloc_type (type);
1989 break;
1991 case EM_MN10200:
1992 case EM_CYGNUS_MN10200:
1993 rtype = elf_mn10200_reloc_type (type);
1994 break;
1996 case EM_FR30:
1997 case EM_CYGNUS_FR30:
1998 rtype = elf_fr30_reloc_type (type);
1999 break;
2001 case EM_CYGNUS_FRV:
2002 rtype = elf_frv_reloc_type (type);
2003 break;
2005 case EM_CSKY:
2006 rtype = elf_csky_reloc_type (type);
2007 break;
2009 case EM_FT32:
2010 rtype = elf_ft32_reloc_type (type);
2011 break;
2013 case EM_MCORE:
2014 rtype = elf_mcore_reloc_type (type);
2015 break;
2017 case EM_MMIX:
2018 rtype = elf_mmix_reloc_type (type);
2019 break;
2021 case EM_MOXIE:
2022 rtype = elf_moxie_reloc_type (type);
2023 break;
2025 case EM_MSP430:
2026 if (uses_msp430x_relocs (filedata))
2028 rtype = elf_msp430x_reloc_type (type);
2029 break;
2031 /* Fall through. */
2032 case EM_MSP430_OLD:
2033 rtype = elf_msp430_reloc_type (type);
2034 break;
2036 case EM_NDS32:
2037 rtype = elf_nds32_reloc_type (type);
2038 break;
2040 case EM_PPC:
2041 rtype = elf_ppc_reloc_type (type);
2042 break;
2044 case EM_PPC64:
2045 rtype = elf_ppc64_reloc_type (type);
2046 break;
2048 case EM_MIPS:
2049 case EM_MIPS_RS3_LE:
2050 rtype = elf_mips_reloc_type (type);
2051 break;
2053 case EM_RISCV:
2054 rtype = elf_riscv_reloc_type (type);
2055 break;
2057 case EM_ALPHA:
2058 rtype = elf_alpha_reloc_type (type);
2059 break;
2061 case EM_ARM:
2062 rtype = elf_arm_reloc_type (type);
2063 break;
2065 case EM_ARC:
2066 case EM_ARC_COMPACT:
2067 case EM_ARC_COMPACT2:
2068 case EM_ARC_COMPACT3:
2069 case EM_ARC_COMPACT3_64:
2070 rtype = elf_arc_reloc_type (type);
2071 break;
2073 case EM_PARISC:
2074 rtype = elf_hppa_reloc_type (type);
2075 break;
2077 case EM_H8_300:
2078 case EM_H8_300H:
2079 case EM_H8S:
2080 rtype = elf_h8_reloc_type (type);
2081 break;
2083 case EM_OR1K:
2084 rtype = elf_or1k_reloc_type (type);
2085 break;
2087 case EM_PJ:
2088 case EM_PJ_OLD:
2089 rtype = elf_pj_reloc_type (type);
2090 break;
2091 case EM_IA_64:
2092 rtype = elf_ia64_reloc_type (type);
2093 break;
2095 case EM_KVX:
2096 rtype = elf_kvx_reloc_type (type);
2097 break;
2099 case EM_CRIS:
2100 rtype = elf_cris_reloc_type (type);
2101 break;
2103 case EM_860:
2104 rtype = elf_i860_reloc_type (type);
2105 break;
2107 case EM_X86_64:
2108 case EM_L1OM:
2109 case EM_K1OM:
2110 rtype = elf_x86_64_reloc_type (type);
2111 break;
2113 case EM_S370:
2114 rtype = i370_reloc_type (type);
2115 break;
2117 case EM_S390_OLD:
2118 case EM_S390:
2119 rtype = elf_s390_reloc_type (type);
2120 break;
2122 case EM_SCORE:
2123 rtype = elf_score_reloc_type (type);
2124 break;
2126 case EM_XSTORMY16:
2127 rtype = elf_xstormy16_reloc_type (type);
2128 break;
2130 case EM_CRX:
2131 rtype = elf_crx_reloc_type (type);
2132 break;
2134 case EM_VAX:
2135 rtype = elf_vax_reloc_type (type);
2136 break;
2138 case EM_VISIUM:
2139 rtype = elf_visium_reloc_type (type);
2140 break;
2142 case EM_BPF:
2143 rtype = elf_bpf_reloc_type (type);
2144 break;
2146 case EM_ADAPTEVA_EPIPHANY:
2147 rtype = elf_epiphany_reloc_type (type);
2148 break;
2150 case EM_IP2K:
2151 case EM_IP2K_OLD:
2152 rtype = elf_ip2k_reloc_type (type);
2153 break;
2155 case EM_IQ2000:
2156 rtype = elf_iq2000_reloc_type (type);
2157 break;
2159 case EM_XTENSA_OLD:
2160 case EM_XTENSA:
2161 rtype = elf_xtensa_reloc_type (type);
2162 break;
2164 case EM_LATTICEMICO32:
2165 rtype = elf_lm32_reloc_type (type);
2166 break;
2168 case EM_M32C_OLD:
2169 case EM_M32C:
2170 rtype = elf_m32c_reloc_type (type);
2171 break;
2173 case EM_MT:
2174 rtype = elf_mt_reloc_type (type);
2175 break;
2177 case EM_BLACKFIN:
2178 rtype = elf_bfin_reloc_type (type);
2179 break;
2181 case EM_CYGNUS_MEP:
2182 rtype = elf_mep_reloc_type (type);
2183 break;
2185 case EM_CR16:
2186 rtype = elf_cr16_reloc_type (type);
2187 break;
2189 case EM_MICROBLAZE:
2190 case EM_MICROBLAZE_OLD:
2191 rtype = elf_microblaze_reloc_type (type);
2192 break;
2194 case EM_RL78:
2195 rtype = elf_rl78_reloc_type (type);
2196 break;
2198 case EM_RX:
2199 rtype = elf_rx_reloc_type (type);
2200 break;
2202 case EM_METAG:
2203 rtype = elf_metag_reloc_type (type);
2204 break;
2206 case EM_TI_C6000:
2207 rtype = elf_tic6x_reloc_type (type);
2208 break;
2210 case EM_TILEGX:
2211 rtype = elf_tilegx_reloc_type (type);
2212 break;
2214 case EM_TILEPRO:
2215 rtype = elf_tilepro_reloc_type (type);
2216 break;
2218 case EM_WEBASSEMBLY:
2219 rtype = elf_wasm32_reloc_type (type);
2220 break;
2222 case EM_XGATE:
2223 rtype = elf_xgate_reloc_type (type);
2224 break;
2226 case EM_ALTERA_NIOS2:
2227 rtype = elf_nios2_reloc_type (type);
2228 break;
2230 case EM_TI_PRU:
2231 rtype = elf_pru_reloc_type (type);
2232 break;
2234 case EM_NFP:
2235 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
2236 rtype = elf_nfp3200_reloc_type (type);
2237 else
2238 rtype = elf_nfp_reloc_type (type);
2239 break;
2241 case EM_Z80:
2242 rtype = elf_z80_reloc_type (type);
2243 break;
2245 case EM_LOONGARCH:
2246 rtype = elf_loongarch_reloc_type (type);
2247 break;
2249 case EM_AMDGPU:
2250 rtype = elf_amdgpu_reloc_type (type);
2251 break;
2254 if (rtype == NULL)
2255 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
2256 else
2257 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
2259 if (filedata->file_header.e_machine == EM_ALPHA
2260 && rtype != NULL
2261 && streq (rtype, "R_ALPHA_LITUSE")
2262 && rel_type == reltype_rela)
2264 switch (rels[i].r_addend)
2266 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
2267 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
2268 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
2269 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
2270 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
2271 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
2272 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
2273 default: rtype = NULL;
2276 if (rtype)
2277 printf (" (%s)", rtype);
2278 else
2280 putchar (' ');
2281 printf (_("<unknown addend: %" PRIx64 ">"),
2282 rels[i].r_addend);
2283 res = false;
2286 else if (symtab_index)
2288 if (symtab == NULL || symtab_index >= nsyms)
2290 error (_(" bad symbol index: %08lx in reloc\n"),
2291 (unsigned long) symtab_index);
2292 res = false;
2294 else
2296 Elf_Internal_Sym * psym;
2297 const char * version_string;
2298 enum versioned_symbol_info sym_info;
2299 unsigned short vna_other;
2301 psym = symtab + symtab_index;
2303 version_string
2304 = get_symbol_version_string (filedata, is_dynsym,
2305 strtab, strtablen,
2306 symtab_index,
2307 psym,
2308 &sym_info,
2309 &vna_other);
2311 printf (" ");
2313 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
2315 const char * name;
2316 unsigned int len;
2317 unsigned int width = is_32bit_elf ? 8 : 14;
2319 /* Relocations against GNU_IFUNC symbols do not use the value
2320 of the symbol as the address to relocate against. Instead
2321 they invoke the function named by the symbol and use its
2322 result as the address for relocation.
2324 To indicate this to the user, do not display the value of
2325 the symbol in the "Symbols's Value" field. Instead show
2326 its name followed by () as a hint that the symbol is
2327 invoked. */
2329 if (strtab == NULL
2330 || psym->st_name == 0
2331 || psym->st_name >= strtablen)
2332 name = "??";
2333 else
2334 name = strtab + psym->st_name;
2336 len = print_symbol_name (width, name);
2337 if (version_string)
2338 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2339 version_string);
2340 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
2342 else
2344 print_vma (psym->st_value, LONG_HEX);
2346 printf (is_32bit_elf ? " " : " ");
2349 if (psym->st_name == 0)
2351 const char * sec_name = "<null>";
2353 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
2354 sec_name = printable_section_name_from_index
2355 (filedata, psym->st_shndx, NULL);
2357 print_symbol_name (22, sec_name);
2359 else if (strtab == NULL)
2360 printf (_("<string table index: %3ld>"), psym->st_name);
2361 else if (psym->st_name >= strtablen)
2363 error (_("<corrupt string table index: %3ld>\n"),
2364 psym->st_name);
2365 res = false;
2367 else
2369 print_symbol_name (22, strtab + psym->st_name);
2370 if (version_string)
2371 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2372 version_string);
2375 if (rel_type == reltype_rela)
2377 uint64_t off = rels[i].r_addend;
2379 if ((int64_t) off < 0)
2380 printf (" - %" PRIx64, -off);
2381 else
2382 printf (" + %" PRIx64, off);
2386 else if (rel_type == reltype_rela)
2388 uint64_t off = rels[i].r_addend;
2390 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
2391 if ((int64_t) off < 0)
2392 printf ("-%" PRIx64, -off);
2393 else
2394 printf ("%" PRIx64, off);
2397 if (filedata->file_header.e_machine == EM_SPARCV9
2398 && rtype != NULL
2399 && streq (rtype, "R_SPARC_OLO10"))
2400 printf (" + %" PRIx64, ELF64_R_TYPE_DATA (inf));
2402 putchar ('\n');
2404 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2406 uint64_t type2 = ELF64_MIPS_R_TYPE2 (inf);
2407 uint64_t type3 = ELF64_MIPS_R_TYPE3 (inf);
2408 const char * rtype2 = elf_mips_reloc_type (type2);
2409 const char * rtype3 = elf_mips_reloc_type (type3);
2411 printf (" Type2: ");
2413 if (rtype2 == NULL)
2414 printf (_("unrecognized: %-7lx"),
2415 (unsigned long) type2 & 0xffffffff);
2416 else
2417 printf ("%-17.17s", rtype2);
2419 printf ("\n Type3: ");
2421 if (rtype3 == NULL)
2422 printf (_("unrecognized: %-7lx"),
2423 (unsigned long) type3 & 0xffffffff);
2424 else
2425 printf ("%-17.17s", rtype3);
2427 putchar ('\n');
2431 free (rels);
2433 return res;
2436 static const char *
2437 get_aarch64_dynamic_type (unsigned long type)
2439 switch (type)
2441 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
2442 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2443 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
2444 default:
2445 return NULL;
2449 static const char *
2450 get_mips_dynamic_type (unsigned long type)
2452 switch (type)
2454 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
2455 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
2456 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
2457 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
2458 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
2459 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
2460 case DT_MIPS_MSYM: return "MIPS_MSYM";
2461 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2462 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2463 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
2464 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
2465 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
2466 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
2467 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
2468 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
2469 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
2470 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
2471 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
2472 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
2473 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
2474 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
2475 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
2476 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
2477 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
2478 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
2479 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
2480 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
2481 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
2482 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
2483 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
2484 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2485 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
2486 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
2487 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
2488 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
2489 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2490 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
2491 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
2492 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
2493 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
2494 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
2495 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
2496 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
2497 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
2498 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
2499 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
2500 case DT_MIPS_XHASH: return "MIPS_XHASH";
2501 default:
2502 return NULL;
2506 static const char *
2507 get_sparc64_dynamic_type (unsigned long type)
2509 switch (type)
2511 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
2512 default:
2513 return NULL;
2517 static const char *
2518 get_ppc_dynamic_type (unsigned long type)
2520 switch (type)
2522 case DT_PPC_GOT: return "PPC_GOT";
2523 case DT_PPC_OPT: return "PPC_OPT";
2524 default:
2525 return NULL;
2529 static const char *
2530 get_ppc64_dynamic_type (unsigned long type)
2532 switch (type)
2534 case DT_PPC64_GLINK: return "PPC64_GLINK";
2535 case DT_PPC64_OPD: return "PPC64_OPD";
2536 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
2537 case DT_PPC64_OPT: return "PPC64_OPT";
2538 default:
2539 return NULL;
2543 static const char *
2544 get_parisc_dynamic_type (unsigned long type)
2546 switch (type)
2548 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
2549 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
2550 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
2551 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
2552 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
2553 case DT_HP_PREINIT: return "HP_PREINIT";
2554 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
2555 case DT_HP_NEEDED: return "HP_NEEDED";
2556 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
2557 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2558 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2559 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2560 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
2561 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2562 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2563 case DT_HP_FILTERED: return "HP_FILTERED";
2564 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2565 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2566 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2567 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2568 case DT_PLT: return "PLT";
2569 case DT_PLT_SIZE: return "PLT_SIZE";
2570 case DT_DLT: return "DLT";
2571 case DT_DLT_SIZE: return "DLT_SIZE";
2572 default:
2573 return NULL;
2577 static const char *
2578 get_ia64_dynamic_type (unsigned long type)
2580 switch (type)
2582 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2583 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2584 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2585 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2586 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2587 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2588 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2589 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2590 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2591 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2592 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2593 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2594 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2595 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2596 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2597 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2598 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2599 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2600 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2601 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2602 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2603 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2604 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2605 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2606 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2607 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2608 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2609 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2610 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2611 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2612 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
2613 default:
2614 return NULL;
2618 static const char *
2619 get_solaris_section_type (unsigned long type)
2621 switch (type)
2623 case 0x6fffffee: return "SUNW_ancillary";
2624 case 0x6fffffef: return "SUNW_capchain";
2625 case 0x6ffffff0: return "SUNW_capinfo";
2626 case 0x6ffffff1: return "SUNW_symsort";
2627 case 0x6ffffff2: return "SUNW_tlssort";
2628 case 0x6ffffff3: return "SUNW_LDYNSYM";
2629 case 0x6ffffff4: return "SUNW_dof";
2630 case 0x6ffffff5: return "SUNW_cap";
2631 case 0x6ffffff6: return "SUNW_SIGNATURE";
2632 case 0x6ffffff7: return "SUNW_ANNOTATE";
2633 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2634 case 0x6ffffff9: return "SUNW_DEBUG";
2635 case 0x6ffffffa: return "SUNW_move";
2636 case 0x6ffffffb: return "SUNW_COMDAT";
2637 case 0x6ffffffc: return "SUNW_syminfo";
2638 case 0x6ffffffd: return "SUNW_verdef";
2639 case 0x6ffffffe: return "SUNW_verneed";
2640 case 0x6fffffff: return "SUNW_versym";
2641 case 0x70000000: return "SPARC_GOTDATA";
2642 default: return NULL;
2646 static const char *
2647 get_alpha_dynamic_type (unsigned long type)
2649 switch (type)
2651 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
2652 default: return NULL;
2656 static const char *
2657 get_score_dynamic_type (unsigned long type)
2659 switch (type)
2661 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2662 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2663 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2664 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2665 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2666 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
2667 default: return NULL;
2671 static const char *
2672 get_tic6x_dynamic_type (unsigned long type)
2674 switch (type)
2676 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2677 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2678 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2679 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2680 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2681 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
2682 default: return NULL;
2686 static const char *
2687 get_nios2_dynamic_type (unsigned long type)
2689 switch (type)
2691 case DT_NIOS2_GP: return "NIOS2_GP";
2692 default: return NULL;
2696 static const char *
2697 get_solaris_dynamic_type (unsigned long type)
2699 switch (type)
2701 case 0x6000000d: return "SUNW_AUXILIARY";
2702 case 0x6000000e: return "SUNW_RTLDINF";
2703 case 0x6000000f: return "SUNW_FILTER";
2704 case 0x60000010: return "SUNW_CAP";
2705 case 0x60000011: return "SUNW_SYMTAB";
2706 case 0x60000012: return "SUNW_SYMSZ";
2707 case 0x60000013: return "SUNW_SORTENT";
2708 case 0x60000014: return "SUNW_SYMSORT";
2709 case 0x60000015: return "SUNW_SYMSORTSZ";
2710 case 0x60000016: return "SUNW_TLSSORT";
2711 case 0x60000017: return "SUNW_TLSSORTSZ";
2712 case 0x60000018: return "SUNW_CAPINFO";
2713 case 0x60000019: return "SUNW_STRPAD";
2714 case 0x6000001a: return "SUNW_CAPCHAIN";
2715 case 0x6000001b: return "SUNW_LDMACH";
2716 case 0x6000001d: return "SUNW_CAPCHAINENT";
2717 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2718 case 0x60000021: return "SUNW_PARENT";
2719 case 0x60000023: return "SUNW_ASLR";
2720 case 0x60000025: return "SUNW_RELAX";
2721 case 0x60000029: return "SUNW_NXHEAP";
2722 case 0x6000002b: return "SUNW_NXSTACK";
2724 case 0x70000001: return "SPARC_REGISTER";
2725 case 0x7ffffffd: return "AUXILIARY";
2726 case 0x7ffffffe: return "USED";
2727 case 0x7fffffff: return "FILTER";
2729 default: return NULL;
2733 static const char *
2734 get_riscv_dynamic_type (unsigned long type)
2736 switch (type)
2738 case DT_RISCV_VARIANT_CC: return "RISCV_VARIANT_CC";
2739 default:
2740 return NULL;
2744 static const char *
2745 get_x86_64_dynamic_type (unsigned long type)
2747 switch (type)
2749 case DT_X86_64_PLT:
2750 return "DT_X86_64_PLT";
2751 case DT_X86_64_PLTSZ:
2752 return "DT_X86_64_PLTSZ";
2753 case DT_X86_64_PLTENT:
2754 return "DT_X86_64_PLTENT";
2755 default:
2756 return NULL;
2760 static const char *
2761 get_dynamic_type (Filedata * filedata, unsigned long type)
2763 static char buff[64];
2765 switch (type)
2767 case DT_NULL: return "NULL";
2768 case DT_NEEDED: return "NEEDED";
2769 case DT_PLTRELSZ: return "PLTRELSZ";
2770 case DT_PLTGOT: return "PLTGOT";
2771 case DT_HASH: return "HASH";
2772 case DT_STRTAB: return "STRTAB";
2773 case DT_SYMTAB: return "SYMTAB";
2774 case DT_RELA: return "RELA";
2775 case DT_RELASZ: return "RELASZ";
2776 case DT_RELAENT: return "RELAENT";
2777 case DT_STRSZ: return "STRSZ";
2778 case DT_SYMENT: return "SYMENT";
2779 case DT_INIT: return "INIT";
2780 case DT_FINI: return "FINI";
2781 case DT_SONAME: return "SONAME";
2782 case DT_RPATH: return "RPATH";
2783 case DT_SYMBOLIC: return "SYMBOLIC";
2784 case DT_REL: return "REL";
2785 case DT_RELSZ: return "RELSZ";
2786 case DT_RELENT: return "RELENT";
2787 case DT_RELR: return "RELR";
2788 case DT_RELRSZ: return "RELRSZ";
2789 case DT_RELRENT: return "RELRENT";
2790 case DT_PLTREL: return "PLTREL";
2791 case DT_DEBUG: return "DEBUG";
2792 case DT_TEXTREL: return "TEXTREL";
2793 case DT_JMPREL: return "JMPREL";
2794 case DT_BIND_NOW: return "BIND_NOW";
2795 case DT_INIT_ARRAY: return "INIT_ARRAY";
2796 case DT_FINI_ARRAY: return "FINI_ARRAY";
2797 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2798 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
2799 case DT_RUNPATH: return "RUNPATH";
2800 case DT_FLAGS: return "FLAGS";
2802 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2803 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
2804 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
2806 case DT_CHECKSUM: return "CHECKSUM";
2807 case DT_PLTPADSZ: return "PLTPADSZ";
2808 case DT_MOVEENT: return "MOVEENT";
2809 case DT_MOVESZ: return "MOVESZ";
2810 case DT_FEATURE: return "FEATURE";
2811 case DT_POSFLAG_1: return "POSFLAG_1";
2812 case DT_SYMINSZ: return "SYMINSZ";
2813 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
2815 case DT_ADDRRNGLO: return "ADDRRNGLO";
2816 case DT_CONFIG: return "CONFIG";
2817 case DT_DEPAUDIT: return "DEPAUDIT";
2818 case DT_AUDIT: return "AUDIT";
2819 case DT_PLTPAD: return "PLTPAD";
2820 case DT_MOVETAB: return "MOVETAB";
2821 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
2823 case DT_VERSYM: return "VERSYM";
2825 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2826 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
2827 case DT_RELACOUNT: return "RELACOUNT";
2828 case DT_RELCOUNT: return "RELCOUNT";
2829 case DT_FLAGS_1: return "FLAGS_1";
2830 case DT_VERDEF: return "VERDEF";
2831 case DT_VERDEFNUM: return "VERDEFNUM";
2832 case DT_VERNEED: return "VERNEED";
2833 case DT_VERNEEDNUM: return "VERNEEDNUM";
2835 case DT_AUXILIARY: return "AUXILIARY";
2836 case DT_USED: return "USED";
2837 case DT_FILTER: return "FILTER";
2839 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2840 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2841 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2842 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2843 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
2844 case DT_GNU_HASH: return "GNU_HASH";
2845 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
2847 default:
2848 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2850 const char * result;
2852 switch (filedata->file_header.e_machine)
2854 case EM_AARCH64:
2855 result = get_aarch64_dynamic_type (type);
2856 break;
2857 case EM_MIPS:
2858 case EM_MIPS_RS3_LE:
2859 result = get_mips_dynamic_type (type);
2860 break;
2861 case EM_SPARCV9:
2862 result = get_sparc64_dynamic_type (type);
2863 break;
2864 case EM_PPC:
2865 result = get_ppc_dynamic_type (type);
2866 break;
2867 case EM_PPC64:
2868 result = get_ppc64_dynamic_type (type);
2869 break;
2870 case EM_IA_64:
2871 result = get_ia64_dynamic_type (type);
2872 break;
2873 case EM_ALPHA:
2874 result = get_alpha_dynamic_type (type);
2875 break;
2876 case EM_SCORE:
2877 result = get_score_dynamic_type (type);
2878 break;
2879 case EM_TI_C6000:
2880 result = get_tic6x_dynamic_type (type);
2881 break;
2882 case EM_ALTERA_NIOS2:
2883 result = get_nios2_dynamic_type (type);
2884 break;
2885 case EM_RISCV:
2886 result = get_riscv_dynamic_type (type);
2887 break;
2888 case EM_X86_64:
2889 result = get_x86_64_dynamic_type (type);
2890 break;
2891 default:
2892 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
2893 result = get_solaris_dynamic_type (type);
2894 else
2895 result = NULL;
2896 break;
2899 if (result != NULL)
2900 return result;
2902 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
2904 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
2905 || (filedata->file_header.e_machine == EM_PARISC
2906 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
2908 const char * result;
2910 switch (filedata->file_header.e_machine)
2912 case EM_PARISC:
2913 result = get_parisc_dynamic_type (type);
2914 break;
2915 case EM_IA_64:
2916 result = get_ia64_dynamic_type (type);
2917 break;
2918 default:
2919 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
2920 result = get_solaris_dynamic_type (type);
2921 else
2922 result = NULL;
2923 break;
2926 if (result != NULL)
2927 return result;
2929 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2930 type);
2932 else
2933 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
2935 return buff;
2939 static bool get_program_headers (Filedata *);
2940 static bool get_dynamic_section (Filedata *);
2942 static void
2943 locate_dynamic_section (Filedata *filedata)
2945 uint64_t dynamic_addr = 0;
2946 uint64_t dynamic_size = 0;
2948 if (filedata->file_header.e_phnum != 0
2949 && get_program_headers (filedata))
2951 Elf_Internal_Phdr *segment;
2952 unsigned int i;
2954 for (i = 0, segment = filedata->program_headers;
2955 i < filedata->file_header.e_phnum;
2956 i++, segment++)
2958 if (segment->p_type == PT_DYNAMIC)
2960 dynamic_addr = segment->p_offset;
2961 dynamic_size = segment->p_filesz;
2963 if (filedata->section_headers != NULL)
2965 Elf_Internal_Shdr *sec;
2967 sec = find_section (filedata, ".dynamic");
2968 if (sec != NULL)
2970 if (sec->sh_size == 0
2971 || sec->sh_type == SHT_NOBITS)
2973 dynamic_addr = 0;
2974 dynamic_size = 0;
2976 else
2978 dynamic_addr = sec->sh_offset;
2979 dynamic_size = sec->sh_size;
2984 if (dynamic_addr > filedata->file_size
2985 || (dynamic_size > filedata->file_size - dynamic_addr))
2987 dynamic_addr = 0;
2988 dynamic_size = 0;
2990 break;
2994 filedata->dynamic_addr = dynamic_addr;
2995 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
2998 static bool
2999 is_pie (Filedata *filedata)
3001 Elf_Internal_Dyn *entry;
3003 if (filedata->dynamic_size == 0)
3004 locate_dynamic_section (filedata);
3005 if (filedata->dynamic_size <= 1)
3006 return false;
3008 if (!get_dynamic_section (filedata))
3009 return false;
3011 for (entry = filedata->dynamic_section;
3012 entry < filedata->dynamic_section + filedata->dynamic_nent;
3013 entry++)
3015 if (entry->d_tag == DT_FLAGS_1)
3017 if ((entry->d_un.d_val & DF_1_PIE) != 0)
3018 return true;
3019 break;
3022 return false;
3025 static char *
3026 get_file_type (Filedata *filedata)
3028 unsigned e_type = filedata->file_header.e_type;
3029 static char buff[64];
3031 switch (e_type)
3033 case ET_NONE: return _("NONE (None)");
3034 case ET_REL: return _("REL (Relocatable file)");
3035 case ET_EXEC: return _("EXEC (Executable file)");
3036 case ET_DYN:
3037 if (is_pie (filedata))
3038 return _("DYN (Position-Independent Executable file)");
3039 else
3040 return _("DYN (Shared object file)");
3041 case ET_CORE: return _("CORE (Core file)");
3043 default:
3044 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
3045 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
3046 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
3047 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
3048 else
3049 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
3050 return buff;
3054 static char *
3055 get_machine_name (unsigned e_machine)
3057 static char buff[64]; /* XXX */
3059 switch (e_machine)
3061 /* Please keep this switch table sorted by increasing EM_ value. */
3062 /* 0 */
3063 case EM_NONE: return _("None");
3064 case EM_M32: return "WE32100";
3065 case EM_SPARC: return "Sparc";
3066 case EM_386: return "Intel 80386";
3067 case EM_68K: return "MC68000";
3068 case EM_88K: return "MC88000";
3069 case EM_IAMCU: return "Intel MCU";
3070 case EM_860: return "Intel 80860";
3071 case EM_MIPS: return "MIPS R3000";
3072 case EM_S370: return "IBM System/370";
3073 /* 10 */
3074 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
3075 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
3076 case EM_PARISC: return "HPPA";
3077 case EM_VPP550: return "Fujitsu VPP500";
3078 case EM_SPARC32PLUS: return "Sparc v8+" ;
3079 case EM_960: return "Intel 80960";
3080 case EM_PPC: return "PowerPC";
3081 /* 20 */
3082 case EM_PPC64: return "PowerPC64";
3083 case EM_S390_OLD:
3084 case EM_S390: return "IBM S/390";
3085 case EM_SPU: return "SPU";
3086 /* 30 */
3087 case EM_V800: return "Renesas V850 (using RH850 ABI)";
3088 case EM_FR20: return "Fujitsu FR20";
3089 case EM_RH32: return "TRW RH32";
3090 case EM_MCORE: return "MCORE";
3091 /* 40 */
3092 case EM_ARM: return "ARM";
3093 case EM_OLD_ALPHA: return "Digital Alpha (old)";
3094 case EM_SH: return "Renesas / SuperH SH";
3095 case EM_SPARCV9: return "Sparc v9";
3096 case EM_TRICORE: return "Siemens Tricore";
3097 case EM_ARC: return "ARC";
3098 case EM_H8_300: return "Renesas H8/300";
3099 case EM_H8_300H: return "Renesas H8/300H";
3100 case EM_H8S: return "Renesas H8S";
3101 case EM_H8_500: return "Renesas H8/500";
3102 /* 50 */
3103 case EM_IA_64: return "Intel IA-64";
3104 case EM_MIPS_X: return "Stanford MIPS-X";
3105 case EM_COLDFIRE: return "Motorola Coldfire";
3106 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
3107 case EM_MMA: return "Fujitsu Multimedia Accelerator";
3108 case EM_PCP: return "Siemens PCP";
3109 case EM_NCPU: return "Sony nCPU embedded RISC processor";
3110 case EM_NDR1: return "Denso NDR1 microprocessor";
3111 case EM_STARCORE: return "Motorola Star*Core processor";
3112 case EM_ME16: return "Toyota ME16 processor";
3113 /* 60 */
3114 case EM_ST100: return "STMicroelectronics ST100 processor";
3115 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
3116 case EM_X86_64: return "Advanced Micro Devices X86-64";
3117 case EM_PDSP: return "Sony DSP processor";
3118 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
3119 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
3120 case EM_FX66: return "Siemens FX66 microcontroller";
3121 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
3122 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
3123 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
3124 /* 70 */
3125 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
3126 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
3127 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
3128 case EM_SVX: return "Silicon Graphics SVx";
3129 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
3130 case EM_VAX: return "Digital VAX";
3131 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
3132 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
3133 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
3134 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
3135 /* 80 */
3136 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
3137 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3138 case EM_PRISM: return "Vitesse Prism";
3139 case EM_AVR_OLD:
3140 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
3141 case EM_CYGNUS_FR30:
3142 case EM_FR30: return "Fujitsu FR30";
3143 case EM_CYGNUS_D10V:
3144 case EM_D10V: return "d10v";
3145 case EM_CYGNUS_D30V:
3146 case EM_D30V: return "d30v";
3147 case EM_CYGNUS_V850:
3148 case EM_V850: return "Renesas V850";
3149 case EM_CYGNUS_M32R:
3150 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
3151 case EM_CYGNUS_MN10300:
3152 case EM_MN10300: return "mn10300";
3153 /* 90 */
3154 case EM_CYGNUS_MN10200:
3155 case EM_MN10200: return "mn10200";
3156 case EM_PJ: return "picoJava";
3157 case EM_OR1K: return "OpenRISC 1000";
3158 case EM_ARC_COMPACT: return "ARCompact";
3159 case EM_XTENSA_OLD:
3160 case EM_XTENSA: return "Tensilica Xtensa Processor";
3161 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
3162 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
3163 case EM_NS32K: return "National Semiconductor 32000 series";
3164 case EM_TPC: return "Tenor Network TPC processor";
3165 case EM_SNP1K: return "Trebia SNP 1000 processor";
3166 /* 100 */
3167 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
3168 case EM_IP2K_OLD:
3169 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3170 case EM_MAX: return "MAX Processor";
3171 case EM_CR: return "National Semiconductor CompactRISC";
3172 case EM_F2MC16: return "Fujitsu F2MC16";
3173 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
3174 case EM_BLACKFIN: return "Analog Devices Blackfin";
3175 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
3176 case EM_SEP: return "Sharp embedded microprocessor";
3177 case EM_ARCA: return "Arca RISC microprocessor";
3178 /* 110 */
3179 case EM_UNICORE: return "Unicore";
3180 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
3181 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
3182 case EM_ALTERA_NIOS2: return "Altera Nios II";
3183 case EM_CRX: return "National Semiconductor CRX microprocessor";
3184 case EM_XGATE: return "Motorola XGATE embedded processor";
3185 case EM_C166:
3186 case EM_XC16X: return "Infineon Technologies xc16x";
3187 case EM_M16C: return "Renesas M16C series microprocessors";
3188 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
3189 case EM_CE: return "Freescale Communication Engine RISC core";
3190 /* 120 */
3191 case EM_M32C: return "Renesas M32c";
3192 /* 130 */
3193 case EM_TSK3000: return "Altium TSK3000 core";
3194 case EM_RS08: return "Freescale RS08 embedded processor";
3195 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
3196 case EM_SCORE: return "SUNPLUS S+Core";
3197 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
3198 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
3199 case EM_LATTICEMICO32: return "Lattice Mico32";
3200 case EM_SE_C17: return "Seiko Epson C17 family";
3201 /* 140 */
3202 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
3203 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
3204 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
3205 case EM_TI_PRU: return "TI PRU I/O processor";
3206 /* 160 */
3207 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
3208 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
3209 case EM_R32C: return "Renesas R32C series microprocessors";
3210 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
3211 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
3212 case EM_8051: return "Intel 8051 and variants";
3213 case EM_STXP7X: return "STMicroelectronics STxP7x family";
3214 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
3215 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
3216 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
3217 /* 170 */
3218 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
3219 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
3220 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
3221 case EM_RX: return "Renesas RX";
3222 case EM_METAG: return "Imagination Technologies Meta processor architecture";
3223 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
3224 case EM_ECOG16: return "Cyan Technology eCOG16 family";
3225 case EM_CR16:
3226 case EM_MICROBLAZE:
3227 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
3228 case EM_ETPU: return "Freescale Extended Time Processing Unit";
3229 case EM_SLE9X: return "Infineon Technologies SLE9X core";
3230 /* 180 */
3231 case EM_L1OM: return "Intel L1OM";
3232 case EM_K1OM: return "Intel K1OM";
3233 case EM_INTEL182: return "Intel (reserved)";
3234 case EM_AARCH64: return "AArch64";
3235 case EM_ARM184: return "ARM (reserved)";
3236 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
3237 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
3238 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
3239 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
3240 /* 190 */
3241 case EM_CUDA: return "NVIDIA CUDA architecture";
3242 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
3243 case EM_CLOUDSHIELD: return "CloudShield architecture family";
3244 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
3245 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
3246 case EM_ARC_COMPACT2: return "ARCv2";
3247 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
3248 case EM_RL78: return "Renesas RL78";
3249 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
3250 case EM_78K0R: return "Renesas 78K0R";
3251 /* 200 */
3252 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
3253 case EM_BA1: return "Beyond BA1 CPU architecture";
3254 case EM_BA2: return "Beyond BA2 CPU architecture";
3255 case EM_XCORE: return "XMOS xCORE processor family";
3256 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
3257 case EM_INTELGT: return "Intel Graphics Technology";
3258 /* 210 */
3259 case EM_KM32: return "KM211 KM32 32-bit processor";
3260 case EM_KMX32: return "KM211 KMX32 32-bit processor";
3261 case EM_KMX16: return "KM211 KMX16 16-bit processor";
3262 case EM_KMX8: return "KM211 KMX8 8-bit processor";
3263 case EM_KVARC: return "KM211 KVARC processor";
3264 case EM_CDP: return "Paneve CDP architecture family";
3265 case EM_COGE: return "Cognitive Smart Memory Processor";
3266 case EM_COOL: return "Bluechip Systems CoolEngine";
3267 case EM_NORC: return "Nanoradio Optimized RISC";
3268 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
3269 /* 220 */
3270 case EM_Z80: return "Zilog Z80";
3271 case EM_VISIUM: return "CDS VISIUMcore processor";
3272 case EM_FT32: return "FTDI Chip FT32";
3273 case EM_MOXIE: return "Moxie";
3274 case EM_AMDGPU: return "AMD GPU";
3275 /* 230 (all reserved) */
3276 /* 240 */
3277 case EM_RISCV: return "RISC-V";
3278 case EM_LANAI: return "Lanai 32-bit processor";
3279 case EM_CEVA: return "CEVA Processor Architecture Family";
3280 case EM_CEVA_X2: return "CEVA X2 Processor Family";
3281 case EM_BPF: return "Linux BPF";
3282 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
3283 case EM_IMG1: return "Imagination Technologies";
3284 /* 250 */
3285 case EM_NFP: return "Netronome Flow Processor";
3286 case EM_VE: return "NEC Vector Engine";
3287 case EM_CSKY: return "C-SKY";
3288 case EM_ARC_COMPACT3_64: return "Synopsys ARCv3 64-bit processor";
3289 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
3290 case EM_ARC_COMPACT3: return "Synopsys ARCv3 32-bit processor";
3291 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
3292 case EM_65816: return "WDC 65816/65C816";
3293 case EM_LOONGARCH: return "LoongArch";
3294 case EM_KF32: return "ChipON KungFu32";
3296 /* Large numbers... */
3297 case EM_MT: return "Morpho Techologies MT processor";
3298 case EM_ALPHA: return "Alpha";
3299 case EM_WEBASSEMBLY: return "Web Assembly";
3300 case EM_DLX: return "OpenDLX";
3301 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3302 case EM_IQ2000: return "Vitesse IQ2000";
3303 case EM_M32C_OLD:
3304 case EM_NIOS32: return "Altera Nios";
3305 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
3306 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
3307 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
3308 case EM_S12Z: return "Freescale S12Z";
3310 default:
3311 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
3312 return buff;
3316 static char *
3317 decode_ARC_machine_flags (char *out, unsigned e_flags, unsigned e_machine)
3319 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
3320 other compilers don't specify an architecture type in the e_flags, and
3321 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
3322 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
3323 architectures.
3325 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
3326 but also sets a specific architecture type in the e_flags field.
3328 However, when decoding the flags we don't worry if we see an
3329 unexpected pairing, for example EM_ARC_COMPACT machine type, with
3330 ARCEM architecture type. */
3332 switch (e_flags & EF_ARC_MACH_MSK)
3334 /* We only expect these to occur for EM_ARC_COMPACT2. */
3335 case EF_ARC_CPU_ARCV2EM:
3336 out = stpcpy (out, ", ARC EM");
3337 break;
3338 case EF_ARC_CPU_ARCV2HS:
3339 out = stpcpy (out, ", ARC HS");
3340 break;
3342 /* We only expect these to occur for EM_ARC_COMPACT. */
3343 case E_ARC_MACH_ARC600:
3344 out = stpcpy (out, ", ARC600");
3345 break;
3346 case E_ARC_MACH_ARC601:
3347 out = stpcpy (out, ", ARC601");
3348 break;
3349 case E_ARC_MACH_ARC700:
3350 out = stpcpy (out, ", ARC700");
3351 break;
3353 /* The only times we should end up here are (a) A corrupt ELF, (b) A
3354 new ELF with new architecture being read by an old version of
3355 readelf, or (c) An ELF built with non-GNU compiler that does not
3356 set the architecture in the e_flags. */
3357 default:
3358 if (e_machine == EM_ARC_COMPACT)
3359 out = stpcpy (out, ", Unknown ARCompact");
3360 else
3361 out = stpcpy (out, ", Unknown ARC");
3362 break;
3365 switch (e_flags & EF_ARC_OSABI_MSK)
3367 case E_ARC_OSABI_ORIG:
3368 out = stpcpy (out, ", (ABI:legacy)");
3369 break;
3370 case E_ARC_OSABI_V2:
3371 out = stpcpy (out, ", (ABI:v2)");
3372 break;
3373 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3374 case E_ARC_OSABI_V3:
3375 out = stpcpy (out, ", v3 no-legacy-syscalls ABI");
3376 break;
3377 case E_ARC_OSABI_V4:
3378 out = stpcpy (out, ", v4 ABI");
3379 break;
3380 default:
3381 out = stpcpy (out, ", unrecognised ARC OSABI flag");
3382 break;
3384 return out;
3387 static char *
3388 decode_ARM_machine_flags (char *out, unsigned e_flags)
3390 unsigned eabi;
3391 bool unknown = false;
3393 eabi = EF_ARM_EABI_VERSION (e_flags);
3394 e_flags &= ~ EF_ARM_EABIMASK;
3396 /* Handle "generic" ARM flags. */
3397 if (e_flags & EF_ARM_RELEXEC)
3399 out = stpcpy (out, ", relocatable executable");
3400 e_flags &= ~ EF_ARM_RELEXEC;
3403 if (e_flags & EF_ARM_PIC)
3405 out = stpcpy (out, ", position independent");
3406 e_flags &= ~ EF_ARM_PIC;
3409 /* Now handle EABI specific flags. */
3410 switch (eabi)
3412 default:
3413 out = stpcpy (out, ", <unrecognized EABI>");
3414 if (e_flags)
3415 unknown = true;
3416 break;
3418 case EF_ARM_EABI_VER1:
3419 out = stpcpy (out, ", Version1 EABI");
3420 while (e_flags)
3422 unsigned flag;
3424 /* Process flags one bit at a time. */
3425 flag = e_flags & - e_flags;
3426 e_flags &= ~ flag;
3428 switch (flag)
3430 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
3431 out = stpcpy (out, ", sorted symbol tables");
3432 break;
3434 default:
3435 unknown = true;
3436 break;
3439 break;
3441 case EF_ARM_EABI_VER2:
3442 out = stpcpy (out, ", Version2 EABI");
3443 while (e_flags)
3445 unsigned flag;
3447 /* Process flags one bit at a time. */
3448 flag = e_flags & - e_flags;
3449 e_flags &= ~ flag;
3451 switch (flag)
3453 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
3454 out = stpcpy (out, ", sorted symbol tables");
3455 break;
3457 case EF_ARM_DYNSYMSUSESEGIDX:
3458 out = stpcpy (out, ", dynamic symbols use segment index");
3459 break;
3461 case EF_ARM_MAPSYMSFIRST:
3462 out = stpcpy (out, ", mapping symbols precede others");
3463 break;
3465 default:
3466 unknown = true;
3467 break;
3470 break;
3472 case EF_ARM_EABI_VER3:
3473 out = stpcpy (out, ", Version3 EABI");
3474 break;
3476 case EF_ARM_EABI_VER4:
3477 out = stpcpy (out, ", Version4 EABI");
3478 while (e_flags)
3480 unsigned flag;
3482 /* Process flags one bit at a time. */
3483 flag = e_flags & - e_flags;
3484 e_flags &= ~ flag;
3486 switch (flag)
3488 case EF_ARM_BE8:
3489 out = stpcpy (out, ", BE8");
3490 break;
3492 case EF_ARM_LE8:
3493 out = stpcpy (out, ", LE8");
3494 break;
3496 default:
3497 unknown = true;
3498 break;
3501 break;
3503 case EF_ARM_EABI_VER5:
3504 out = stpcpy (out, ", Version5 EABI");
3505 while (e_flags)
3507 unsigned flag;
3509 /* Process flags one bit at a time. */
3510 flag = e_flags & - e_flags;
3511 e_flags &= ~ flag;
3513 switch (flag)
3515 case EF_ARM_BE8:
3516 out = stpcpy (out, ", BE8");
3517 break;
3519 case EF_ARM_LE8:
3520 out = stpcpy (out, ", LE8");
3521 break;
3523 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
3524 out = stpcpy (out, ", soft-float ABI");
3525 break;
3527 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
3528 out = stpcpy (out, ", hard-float ABI");
3529 break;
3531 default:
3532 unknown = true;
3533 break;
3536 break;
3538 case EF_ARM_EABI_UNKNOWN:
3539 out = stpcpy (out, ", GNU EABI");
3540 while (e_flags)
3542 unsigned flag;
3544 /* Process flags one bit at a time. */
3545 flag = e_flags & - e_flags;
3546 e_flags &= ~ flag;
3548 switch (flag)
3550 case EF_ARM_INTERWORK:
3551 out = stpcpy (out, ", interworking enabled");
3552 break;
3554 case EF_ARM_APCS_26:
3555 out = stpcpy (out, ", uses APCS/26");
3556 break;
3558 case EF_ARM_APCS_FLOAT:
3559 out = stpcpy (out, ", uses APCS/float");
3560 break;
3562 case EF_ARM_PIC:
3563 out = stpcpy (out, ", position independent");
3564 break;
3566 case EF_ARM_ALIGN8:
3567 out = stpcpy (out, ", 8 bit structure alignment");
3568 break;
3570 case EF_ARM_NEW_ABI:
3571 out = stpcpy (out, ", uses new ABI");
3572 break;
3574 case EF_ARM_OLD_ABI:
3575 out = stpcpy (out, ", uses old ABI");
3576 break;
3578 case EF_ARM_SOFT_FLOAT:
3579 out = stpcpy (out, ", software FP");
3580 break;
3582 case EF_ARM_VFP_FLOAT:
3583 out = stpcpy (out, ", VFP");
3584 break;
3586 case EF_ARM_MAVERICK_FLOAT:
3587 out = stpcpy (out, ", Maverick FP");
3588 break;
3590 default:
3591 unknown = true;
3592 break;
3597 if (unknown)
3598 out = stpcpy (out,_(", <unknown>"));
3599 return out;
3602 static char *
3603 decode_AVR_machine_flags (char *out, unsigned e_flags)
3605 switch (e_flags & EF_AVR_MACH)
3607 case E_AVR_MACH_AVR1:
3608 out = stpcpy (out, ", avr:1");
3609 break;
3610 case E_AVR_MACH_AVR2:
3611 out = stpcpy (out, ", avr:2");
3612 break;
3613 case E_AVR_MACH_AVR25:
3614 out = stpcpy (out, ", avr:25");
3615 break;
3616 case E_AVR_MACH_AVR3:
3617 out = stpcpy (out, ", avr:3");
3618 break;
3619 case E_AVR_MACH_AVR31:
3620 out = stpcpy (out, ", avr:31");
3621 break;
3622 case E_AVR_MACH_AVR35:
3623 out = stpcpy (out, ", avr:35");
3624 break;
3625 case E_AVR_MACH_AVR4:
3626 out = stpcpy (out, ", avr:4");
3627 break;
3628 case E_AVR_MACH_AVR5:
3629 out = stpcpy (out, ", avr:5");
3630 break;
3631 case E_AVR_MACH_AVR51:
3632 out = stpcpy (out, ", avr:51");
3633 break;
3634 case E_AVR_MACH_AVR6:
3635 out = stpcpy (out, ", avr:6");
3636 break;
3637 case E_AVR_MACH_AVRTINY:
3638 out = stpcpy (out, ", avr:100");
3639 break;
3640 case E_AVR_MACH_XMEGA1:
3641 out = stpcpy (out, ", avr:101");
3642 break;
3643 case E_AVR_MACH_XMEGA2:
3644 out = stpcpy (out, ", avr:102");
3645 break;
3646 case E_AVR_MACH_XMEGA3:
3647 out = stpcpy (out, ", avr:103");
3648 break;
3649 case E_AVR_MACH_XMEGA4:
3650 out = stpcpy (out, ", avr:104");
3651 break;
3652 case E_AVR_MACH_XMEGA5:
3653 out = stpcpy (out, ", avr:105");
3654 break;
3655 case E_AVR_MACH_XMEGA6:
3656 out = stpcpy (out, ", avr:106");
3657 break;
3658 case E_AVR_MACH_XMEGA7:
3659 out = stpcpy (out, ", avr:107");
3660 break;
3661 default:
3662 out = stpcpy (out, ", avr:<unknown>");
3663 break;
3666 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
3667 out = stpcpy (out, ", link-relax");
3668 return out;
3671 static char *
3672 decode_BLACKFIN_machine_flags (char *out, unsigned e_flags)
3674 if (e_flags & EF_BFIN_PIC)
3675 out = stpcpy (out, ", PIC");
3677 if (e_flags & EF_BFIN_FDPIC)
3678 out = stpcpy (out, ", FDPIC");
3680 if (e_flags & EF_BFIN_CODE_IN_L1)
3681 out = stpcpy (out, ", code in L1");
3683 if (e_flags & EF_BFIN_DATA_IN_L1)
3684 out = stpcpy (out, ", data in L1");
3685 return out;
3688 static char *
3689 decode_FRV_machine_flags (char *out, unsigned e_flags)
3691 switch (e_flags & EF_FRV_CPU_MASK)
3693 case EF_FRV_CPU_GENERIC:
3694 break;
3696 default:
3697 out = stpcpy (out, ", fr???");
3698 break;
3700 case EF_FRV_CPU_FR300:
3701 out = stpcpy (out, ", fr300");
3702 break;
3704 case EF_FRV_CPU_FR400:
3705 out = stpcpy (out, ", fr400");
3706 break;
3707 case EF_FRV_CPU_FR405:
3708 out = stpcpy (out, ", fr405");
3709 break;
3711 case EF_FRV_CPU_FR450:
3712 out = stpcpy (out, ", fr450");
3713 break;
3715 case EF_FRV_CPU_FR500:
3716 out = stpcpy (out, ", fr500");
3717 break;
3718 case EF_FRV_CPU_FR550:
3719 out = stpcpy (out, ", fr550");
3720 break;
3722 case EF_FRV_CPU_SIMPLE:
3723 out = stpcpy (out, ", simple");
3724 break;
3725 case EF_FRV_CPU_TOMCAT:
3726 out = stpcpy (out, ", tomcat");
3727 break;
3729 return out;
3732 static char *
3733 decode_IA64_machine_flags (char *out, unsigned e_flags, Filedata *filedata)
3735 if ((e_flags & EF_IA_64_ABI64))
3736 out = stpcpy (out, ", 64-bit");
3737 else
3738 out = stpcpy (out, ", 32-bit");
3739 if ((e_flags & EF_IA_64_REDUCEDFP))
3740 out = stpcpy (out, ", reduced fp model");
3741 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3742 out = stpcpy (out, ", no function descriptors, constant gp");
3743 else if ((e_flags & EF_IA_64_CONS_GP))
3744 out = stpcpy (out, ", constant gp");
3745 if ((e_flags & EF_IA_64_ABSOLUTE))
3746 out = stpcpy (out, ", absolute");
3747 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
3749 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3750 out = stpcpy (out, ", vms_linkages");
3751 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3753 case EF_IA_64_VMS_COMCOD_SUCCESS:
3754 break;
3755 case EF_IA_64_VMS_COMCOD_WARNING:
3756 out = stpcpy (out, ", warning");
3757 break;
3758 case EF_IA_64_VMS_COMCOD_ERROR:
3759 out = stpcpy (out, ", error");
3760 break;
3761 case EF_IA_64_VMS_COMCOD_ABORT:
3762 out = stpcpy (out, ", abort");
3763 break;
3764 default:
3765 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3766 e_flags & EF_IA_64_VMS_COMCOD);
3767 out = stpcpy (out, ", <unknown>");
3770 return out;
3773 static char *
3774 decode_LOONGARCH_machine_flags (char *out, unsigned int e_flags)
3776 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
3777 out = stpcpy (out, ", SOFT-FLOAT");
3778 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
3779 out = stpcpy (out, ", SINGLE-FLOAT");
3780 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
3781 out = stpcpy (out, ", DOUBLE-FLOAT");
3783 if (EF_LOONGARCH_IS_OBJ_V0 (e_flags))
3784 out = stpcpy (out, ", OBJ-v0");
3785 else if (EF_LOONGARCH_IS_OBJ_V1 (e_flags))
3786 out = stpcpy (out, ", OBJ-v1");
3787 return out;
3790 static char *
3791 decode_M68K_machine_flags (char *out, unsigned int e_flags)
3793 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
3794 out = stpcpy (out, ", m68000");
3795 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3796 out = stpcpy (out, ", cpu32");
3797 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3798 out = stpcpy (out, ", fido_a");
3799 else
3801 char const *isa = _("unknown");
3802 char const *mac = _("unknown mac");
3803 char const *additional = NULL;
3805 switch (e_flags & EF_M68K_CF_ISA_MASK)
3807 case EF_M68K_CF_ISA_A_NODIV:
3808 isa = "A";
3809 additional = ", nodiv";
3810 break;
3811 case EF_M68K_CF_ISA_A:
3812 isa = "A";
3813 break;
3814 case EF_M68K_CF_ISA_A_PLUS:
3815 isa = "A+";
3816 break;
3817 case EF_M68K_CF_ISA_B_NOUSP:
3818 isa = "B";
3819 additional = ", nousp";
3820 break;
3821 case EF_M68K_CF_ISA_B:
3822 isa = "B";
3823 break;
3824 case EF_M68K_CF_ISA_C:
3825 isa = "C";
3826 break;
3827 case EF_M68K_CF_ISA_C_NODIV:
3828 isa = "C";
3829 additional = ", nodiv";
3830 break;
3832 out = stpcpy (out, ", cf, isa ");
3833 out = stpcpy (out, isa);
3834 if (additional)
3835 out = stpcpy (out, additional);
3836 if (e_flags & EF_M68K_CF_FLOAT)
3837 out = stpcpy (out, ", float");
3838 switch (e_flags & EF_M68K_CF_MAC_MASK)
3840 case 0:
3841 mac = NULL;
3842 break;
3843 case EF_M68K_CF_MAC:
3844 mac = "mac";
3845 break;
3846 case EF_M68K_CF_EMAC:
3847 mac = "emac";
3848 break;
3849 case EF_M68K_CF_EMAC_B:
3850 mac = "emac_b";
3851 break;
3853 if (mac)
3855 out = stpcpy (out, ", ");
3856 out = stpcpy (out, mac);
3859 return out;
3862 static char *
3863 decode_MeP_machine_flags (char *out, unsigned int e_flags)
3865 switch (e_flags & EF_MEP_CPU_MASK)
3867 case EF_MEP_CPU_MEP:
3868 out = stpcpy (out, ", generic MeP");
3869 break;
3870 case EF_MEP_CPU_C2:
3871 out = stpcpy (out, ", MeP C2");
3872 break;
3873 case EF_MEP_CPU_C3:
3874 out = stpcpy (out, ", MeP C3");
3875 break;
3876 case EF_MEP_CPU_C4:
3877 out = stpcpy (out, ", MeP C4");
3878 break;
3879 case EF_MEP_CPU_C5:
3880 out = stpcpy (out, ", MeP C5");
3881 break;
3882 case EF_MEP_CPU_H1:
3883 out = stpcpy (out, ", MeP H1");
3884 break;
3885 default:
3886 out = stpcpy (out, _(", <unknown MeP cpu type>"));
3887 break;
3890 switch (e_flags & EF_MEP_COP_MASK)
3892 case EF_MEP_COP_NONE:
3893 break;
3894 case EF_MEP_COP_AVC:
3895 out = stpcpy (out, ", AVC coprocessor");
3896 break;
3897 case EF_MEP_COP_AVC2:
3898 out = stpcpy (out, ", AVC2 coprocessor");
3899 break;
3900 case EF_MEP_COP_FMAX:
3901 out = stpcpy (out, ", FMAX coprocessor");
3902 break;
3903 case EF_MEP_COP_IVC2:
3904 out = stpcpy (out, ", IVC2 coprocessor");
3905 break;
3906 default:
3907 out = stpcpy (out, _("<unknown MeP copro type>"));
3908 break;
3911 if (e_flags & EF_MEP_LIBRARY)
3912 out = stpcpy (out, ", Built for Library");
3914 if (e_flags & EF_MEP_INDEX_MASK)
3915 out += sprintf (out, ", Configuration Index: %#x",
3916 e_flags & EF_MEP_INDEX_MASK);
3918 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3919 out += sprintf (out, _(", unknown flags bits: %#x"),
3920 e_flags & ~ EF_MEP_ALL_FLAGS);
3921 return out;
3924 static char *
3925 decode_MIPS_machine_flags (char *out, unsigned int e_flags)
3927 if (e_flags & EF_MIPS_NOREORDER)
3928 out = stpcpy (out, ", noreorder");
3930 if (e_flags & EF_MIPS_PIC)
3931 out = stpcpy (out, ", pic");
3933 if (e_flags & EF_MIPS_CPIC)
3934 out = stpcpy (out, ", cpic");
3936 if (e_flags & EF_MIPS_UCODE)
3937 out = stpcpy (out, ", ugen_reserved");
3939 if (e_flags & EF_MIPS_ABI2)
3940 out = stpcpy (out, ", abi2");
3942 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3943 out = stpcpy (out, ", odk first");
3945 if (e_flags & EF_MIPS_32BITMODE)
3946 out = stpcpy (out, ", 32bitmode");
3948 if (e_flags & EF_MIPS_NAN2008)
3949 out = stpcpy (out, ", nan2008");
3951 if (e_flags & EF_MIPS_FP64)
3952 out = stpcpy (out, ", fp64");
3954 switch ((e_flags & EF_MIPS_MACH))
3956 case EF_MIPS_MACH_3900:
3957 out = stpcpy (out, ", 3900");
3958 break;
3959 case EF_MIPS_MACH_4010:
3960 out = stpcpy (out, ", 4010");
3961 break;
3962 case EF_MIPS_MACH_4100:
3963 out = stpcpy (out, ", 4100");
3964 break;
3965 case EF_MIPS_MACH_4111:
3966 out = stpcpy (out, ", 4111");
3967 break;
3968 case EF_MIPS_MACH_4120:
3969 out = stpcpy (out, ", 4120");
3970 break;
3971 case EF_MIPS_MACH_4650:
3972 out = stpcpy (out, ", 4650");
3973 break;
3974 case EF_MIPS_MACH_5400:
3975 out = stpcpy (out, ", 5400");
3976 break;
3977 case EF_MIPS_MACH_5500:
3978 out = stpcpy (out, ", 5500");
3979 break;
3980 case EF_MIPS_MACH_5900:
3981 out = stpcpy (out, ", 5900");
3982 break;
3983 case EF_MIPS_MACH_SB1:
3984 out = stpcpy (out, ", sb1");
3985 break;
3986 case EF_MIPS_MACH_9000:
3987 out = stpcpy (out, ", 9000");
3988 break;
3989 case EF_MIPS_MACH_LS2E:
3990 out = stpcpy (out, ", loongson-2e");
3991 break;
3992 case EF_MIPS_MACH_LS2F:
3993 out = stpcpy (out, ", loongson-2f");
3994 break;
3995 case EF_MIPS_MACH_GS464:
3996 out = stpcpy (out, ", gs464");
3997 break;
3998 case EF_MIPS_MACH_GS464E:
3999 out = stpcpy (out, ", gs464e");
4000 break;
4001 case EF_MIPS_MACH_GS264E:
4002 out = stpcpy (out, ", gs264e");
4003 break;
4004 case EF_MIPS_MACH_OCTEON:
4005 out = stpcpy (out, ", octeon");
4006 break;
4007 case EF_MIPS_MACH_OCTEON2:
4008 out = stpcpy (out, ", octeon2");
4009 break;
4010 case EF_MIPS_MACH_OCTEON3:
4011 out = stpcpy (out, ", octeon3");
4012 break;
4013 case EF_MIPS_MACH_XLR:
4014 out = stpcpy (out, ", xlr");
4015 break;
4016 case EF_MIPS_MACH_IAMR2:
4017 out = stpcpy (out, ", interaptiv-mr2");
4018 break;
4019 case EF_MIPS_MACH_ALLEGREX:
4020 out = stpcpy (out, ", allegrex");
4021 break;
4022 case 0:
4023 /* We simply ignore the field in this case to avoid confusion:
4024 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
4025 extension. */
4026 break;
4027 default:
4028 out = stpcpy (out, _(", unknown CPU"));
4029 break;
4032 switch ((e_flags & EF_MIPS_ABI))
4034 case EF_MIPS_ABI_O32:
4035 out = stpcpy (out, ", o32");
4036 break;
4037 case EF_MIPS_ABI_O64:
4038 out = stpcpy (out, ", o64");
4039 break;
4040 case EF_MIPS_ABI_EABI32:
4041 out = stpcpy (out, ", eabi32");
4042 break;
4043 case EF_MIPS_ABI_EABI64:
4044 out = stpcpy (out, ", eabi64");
4045 break;
4046 case 0:
4047 /* We simply ignore the field in this case to avoid confusion:
4048 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
4049 This means it is likely to be an o32 file, but not for
4050 sure. */
4051 break;
4052 default:
4053 out = stpcpy (out, _(", unknown ABI"));
4054 break;
4057 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
4058 out = stpcpy (out, ", mdmx");
4060 if (e_flags & EF_MIPS_ARCH_ASE_M16)
4061 out = stpcpy (out, ", mips16");
4063 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
4064 out = stpcpy (out, ", micromips");
4066 switch ((e_flags & EF_MIPS_ARCH))
4068 case EF_MIPS_ARCH_1:
4069 out = stpcpy (out, ", mips1");
4070 break;
4071 case EF_MIPS_ARCH_2:
4072 out = stpcpy (out, ", mips2");
4073 break;
4074 case EF_MIPS_ARCH_3:
4075 out = stpcpy (out, ", mips3");
4076 break;
4077 case EF_MIPS_ARCH_4:
4078 out = stpcpy (out, ", mips4");
4079 break;
4080 case EF_MIPS_ARCH_5:
4081 out = stpcpy (out, ", mips5");
4082 break;
4083 case EF_MIPS_ARCH_32:
4084 out = stpcpy (out, ", mips32");
4085 break;
4086 case EF_MIPS_ARCH_32R2:
4087 out = stpcpy (out, ", mips32r2");
4088 break;
4089 case EF_MIPS_ARCH_32R6:
4090 out = stpcpy (out, ", mips32r6");
4091 break;
4092 case EF_MIPS_ARCH_64:
4093 out = stpcpy (out, ", mips64");
4094 break;
4095 case EF_MIPS_ARCH_64R2:
4096 out = stpcpy (out, ", mips64r2");
4097 break;
4098 case EF_MIPS_ARCH_64R6:
4099 out = stpcpy (out, ", mips64r6");
4100 break;
4101 default:
4102 out = stpcpy (out, _(", unknown ISA"));
4103 break;
4105 return out;
4108 static char *
4109 decode_MSP430_machine_flags (char *out, unsigned e_flags)
4111 out = stpcpy (out, _(": architecture variant: "));
4112 switch (e_flags & EF_MSP430_MACH)
4114 case E_MSP430_MACH_MSP430x11:
4115 out = stpcpy (out, "MSP430x11");
4116 break;
4117 case E_MSP430_MACH_MSP430x11x1:
4118 out = stpcpy (out, "MSP430x11x1 ");
4119 break;
4120 case E_MSP430_MACH_MSP430x12:
4121 out = stpcpy (out, "MSP430x12");
4122 break;
4123 case E_MSP430_MACH_MSP430x13:
4124 out = stpcpy (out, "MSP430x13");
4125 break;
4126 case E_MSP430_MACH_MSP430x14:
4127 out = stpcpy (out, "MSP430x14");
4128 break;
4129 case E_MSP430_MACH_MSP430x15:
4130 out = stpcpy (out, "MSP430x15");
4131 break;
4132 case E_MSP430_MACH_MSP430x16:
4133 out = stpcpy (out, "MSP430x16");
4134 break;
4135 case E_MSP430_MACH_MSP430x31:
4136 out = stpcpy (out, "MSP430x31");
4137 break;
4138 case E_MSP430_MACH_MSP430x32:
4139 out = stpcpy (out, "MSP430x32");
4140 break;
4141 case E_MSP430_MACH_MSP430x33:
4142 out = stpcpy (out, "MSP430x33");
4143 break;
4144 case E_MSP430_MACH_MSP430x41:
4145 out = stpcpy (out, "MSP430x41");
4146 break;
4147 case E_MSP430_MACH_MSP430x42:
4148 out = stpcpy (out, "MSP430x42");
4149 break;
4150 case E_MSP430_MACH_MSP430x43:
4151 out = stpcpy (out, "MSP430x43");
4152 break;
4153 case E_MSP430_MACH_MSP430x44:
4154 out = stpcpy (out, "MSP430x44");
4155 break;
4156 case E_MSP430_MACH_MSP430X :
4157 out = stpcpy (out, "MSP430X");
4158 break;
4159 default:
4160 out = stpcpy (out, _(": unknown"));
4161 break;
4164 if (e_flags & ~ EF_MSP430_MACH)
4165 out = stpcpy (out, _(": unknown extra flag bits also present"));
4166 return out;
4169 static char *
4170 decode_NDS32_machine_flags (char *out, unsigned e_flags)
4172 unsigned abi;
4173 unsigned arch;
4174 unsigned config;
4175 unsigned version;
4176 bool has_fpu = false;
4178 static const char *ABI_STRINGS[] =
4180 "ABI v0", /* use r5 as return register; only used in N1213HC */
4181 "ABI v1", /* use r0 as return register */
4182 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
4183 "ABI v2fp", /* for FPU */
4184 "AABI",
4185 "ABI2 FP+"
4187 static const char *VER_STRINGS[] =
4189 "Andes ELF V1.3 or older",
4190 "Andes ELF V1.3.1",
4191 "Andes ELF V1.4"
4193 static const char *ARCH_STRINGS[] =
4196 "Andes Star v1.0",
4197 "Andes Star v2.0",
4198 "Andes Star v3.0",
4199 "Andes Star v3.0m"
4202 abi = EF_NDS_ABI & e_flags;
4203 arch = EF_NDS_ARCH & e_flags;
4204 config = EF_NDS_INST & e_flags;
4205 version = EF_NDS32_ELF_VERSION & e_flags;
4207 switch (abi)
4209 case E_NDS_ABI_V0:
4210 case E_NDS_ABI_V1:
4211 case E_NDS_ABI_V2:
4212 case E_NDS_ABI_V2FP:
4213 case E_NDS_ABI_AABI:
4214 case E_NDS_ABI_V2FP_PLUS:
4215 /* In case there are holes in the array. */
4216 out += sprintf (out, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
4217 break;
4219 default:
4220 out = stpcpy (out, ", <unrecognized ABI>");
4221 break;
4224 switch (version)
4226 case E_NDS32_ELF_VER_1_2:
4227 case E_NDS32_ELF_VER_1_3:
4228 case E_NDS32_ELF_VER_1_4:
4229 out += sprintf (out, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
4230 break;
4232 default:
4233 out = stpcpy (out, ", <unrecognized ELF version number>");
4234 break;
4237 if (E_NDS_ABI_V0 == abi)
4239 /* OLD ABI; only used in N1213HC, has performance extension 1. */
4240 out = stpcpy (out, ", Andes Star v1.0, N1213HC, MAC, PERF1");
4241 if (arch == E_NDS_ARCH_STAR_V1_0)
4242 out = stpcpy (out, ", 16b"); /* has 16-bit instructions */
4243 return out;
4246 switch (arch)
4248 case E_NDS_ARCH_STAR_V1_0:
4249 case E_NDS_ARCH_STAR_V2_0:
4250 case E_NDS_ARCH_STAR_V3_0:
4251 case E_NDS_ARCH_STAR_V3_M:
4252 out += sprintf (out, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
4253 break;
4255 default:
4256 out = stpcpy (out, ", <unrecognized architecture>");
4257 /* ARCH version determines how the e_flags are interpreted.
4258 If it is unknown, we cannot proceed. */
4259 return out;
4262 /* Newer ABI; Now handle architecture specific flags. */
4263 if (arch == E_NDS_ARCH_STAR_V1_0)
4265 if (config & E_NDS32_HAS_MFUSR_PC_INST)
4266 out = stpcpy (out, ", MFUSR_PC");
4268 if (!(config & E_NDS32_HAS_NO_MAC_INST))
4269 out = stpcpy (out, ", MAC");
4271 if (config & E_NDS32_HAS_DIV_INST)
4272 out = stpcpy (out, ", DIV");
4274 if (config & E_NDS32_HAS_16BIT_INST)
4275 out = stpcpy (out, ", 16b");
4277 else
4279 if (config & E_NDS32_HAS_MFUSR_PC_INST)
4281 if (version <= E_NDS32_ELF_VER_1_3)
4282 out = stpcpy (out, ", [B8]");
4283 else
4284 out = stpcpy (out, ", EX9");
4287 if (config & E_NDS32_HAS_MAC_DX_INST)
4288 out = stpcpy (out, ", MAC_DX");
4290 if (config & E_NDS32_HAS_DIV_DX_INST)
4291 out = stpcpy (out, ", DIV_DX");
4293 if (config & E_NDS32_HAS_16BIT_INST)
4295 if (version <= E_NDS32_ELF_VER_1_3)
4296 out = stpcpy (out, ", 16b");
4297 else
4298 out = stpcpy (out, ", IFC");
4302 if (config & E_NDS32_HAS_EXT_INST)
4303 out = stpcpy (out, ", PERF1");
4305 if (config & E_NDS32_HAS_EXT2_INST)
4306 out = stpcpy (out, ", PERF2");
4308 if (config & E_NDS32_HAS_FPU_INST)
4310 has_fpu = true;
4311 out = stpcpy (out, ", FPU_SP");
4314 if (config & E_NDS32_HAS_FPU_DP_INST)
4316 has_fpu = true;
4317 out = stpcpy (out, ", FPU_DP");
4320 if (config & E_NDS32_HAS_FPU_MAC_INST)
4322 has_fpu = true;
4323 out = stpcpy (out, ", FPU_MAC");
4326 if (has_fpu)
4328 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
4330 case E_NDS32_FPU_REG_8SP_4DP:
4331 out = stpcpy (out, ", FPU_REG:8/4");
4332 break;
4333 case E_NDS32_FPU_REG_16SP_8DP:
4334 out = stpcpy (out, ", FPU_REG:16/8");
4335 break;
4336 case E_NDS32_FPU_REG_32SP_16DP:
4337 out = stpcpy (out, ", FPU_REG:32/16");
4338 break;
4339 case E_NDS32_FPU_REG_32SP_32DP:
4340 out = stpcpy (out, ", FPU_REG:32/32");
4341 break;
4345 if (config & E_NDS32_HAS_AUDIO_INST)
4346 out = stpcpy (out, ", AUDIO");
4348 if (config & E_NDS32_HAS_STRING_INST)
4349 out = stpcpy (out, ", STR");
4351 if (config & E_NDS32_HAS_REDUCED_REGS)
4352 out = stpcpy (out, ", 16REG");
4354 if (config & E_NDS32_HAS_VIDEO_INST)
4356 if (version <= E_NDS32_ELF_VER_1_3)
4357 out = stpcpy (out, ", VIDEO");
4358 else
4359 out = stpcpy (out, ", SATURATION");
4362 if (config & E_NDS32_HAS_ENCRIPT_INST)
4363 out = stpcpy (out, ", ENCRP");
4365 if (config & E_NDS32_HAS_L2C_INST)
4366 out = stpcpy (out, ", L2C");
4368 return out;
4371 static char *
4372 decode_PARISC_machine_flags (char *out, unsigned e_flags)
4374 switch (e_flags & EF_PARISC_ARCH)
4376 case EFA_PARISC_1_0:
4377 out = stpcpy (out, ", PA-RISC 1.0");
4378 break;
4379 case EFA_PARISC_1_1:
4380 out = stpcpy (out, ", PA-RISC 1.1");
4381 break;
4382 case EFA_PARISC_2_0:
4383 out = stpcpy (out, ", PA-RISC 2.0");
4384 break;
4385 default:
4386 break;
4388 if (e_flags & EF_PARISC_TRAPNIL)
4389 out = stpcpy (out, ", trapnil");
4390 if (e_flags & EF_PARISC_EXT)
4391 out = stpcpy (out, ", ext");
4392 if (e_flags & EF_PARISC_LSB)
4393 out = stpcpy (out, ", lsb");
4394 if (e_flags & EF_PARISC_WIDE)
4395 out = stpcpy (out, ", wide");
4396 if (e_flags & EF_PARISC_NO_KABP)
4397 out = stpcpy (out, ", no kabp");
4398 if (e_flags & EF_PARISC_LAZYSWAP)
4399 out = stpcpy (out, ", lazyswap");
4400 return out;
4403 static char *
4404 decode_RISCV_machine_flags (char *out, unsigned e_flags)
4406 if (e_flags & EF_RISCV_RVC)
4407 out = stpcpy (out, ", RVC");
4409 if (e_flags & EF_RISCV_RVE)
4410 out = stpcpy (out, ", RVE");
4412 if (e_flags & EF_RISCV_TSO)
4413 out = stpcpy (out, ", TSO");
4415 switch (e_flags & EF_RISCV_FLOAT_ABI)
4417 case EF_RISCV_FLOAT_ABI_SOFT:
4418 out = stpcpy (out, ", soft-float ABI");
4419 break;
4421 case EF_RISCV_FLOAT_ABI_SINGLE:
4422 out = stpcpy (out, ", single-float ABI");
4423 break;
4425 case EF_RISCV_FLOAT_ABI_DOUBLE:
4426 out = stpcpy (out, ", double-float ABI");
4427 break;
4429 case EF_RISCV_FLOAT_ABI_QUAD:
4430 out = stpcpy (out, ", quad-float ABI");
4431 break;
4433 return out;
4436 static char *
4437 decode_RL78_machine_flags (char *out, unsigned e_flags)
4439 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4441 case E_FLAG_RL78_ANY_CPU:
4442 break;
4443 case E_FLAG_RL78_G10:
4444 out = stpcpy (out, ", G10");
4445 break;
4446 case E_FLAG_RL78_G13:
4447 out = stpcpy (out, ", G13");
4448 break;
4449 case E_FLAG_RL78_G14:
4450 out = stpcpy (out, ", G14");
4451 break;
4453 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4454 out = stpcpy (out, ", 64-bit doubles");
4455 return out;
4458 static char *
4459 decode_RX_machine_flags (char *out, unsigned e_flags)
4461 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4462 out = stpcpy (out, ", 64-bit doubles");
4463 if (e_flags & E_FLAG_RX_DSP)
4464 out = stpcpy (out, ", dsp");
4465 if (e_flags & E_FLAG_RX_PID)
4466 out = stpcpy (out, ", pid");
4467 if (e_flags & E_FLAG_RX_ABI)
4468 out = stpcpy (out, ", RX ABI");
4469 if (e_flags & E_FLAG_RX_SINSNS_SET)
4470 out = stpcpy (out, (e_flags & E_FLAG_RX_SINSNS_YES
4471 ? ", uses String instructions"
4472 : ", bans String instructions"));
4473 if (e_flags & E_FLAG_RX_V2)
4474 out = stpcpy (out, ", V2");
4475 if (e_flags & E_FLAG_RX_V3)
4476 out = stpcpy (out, ", V3");
4477 return out;
4480 static char *
4481 decode_SH_machine_flags (char *out, unsigned e_flags)
4483 switch ((e_flags & EF_SH_MACH_MASK))
4485 case EF_SH1:
4486 out = stpcpy (out, ", sh1");
4487 break;
4488 case EF_SH2:
4489 out = stpcpy (out, ", sh2");
4490 break;
4491 case EF_SH3:
4492 out = stpcpy (out, ", sh3");
4493 break;
4494 case EF_SH_DSP:
4495 out = stpcpy (out, ", sh-dsp");
4496 break;
4497 case EF_SH3_DSP:
4498 out = stpcpy (out, ", sh3-dsp");
4499 break;
4500 case EF_SH4AL_DSP:
4501 out = stpcpy (out, ", sh4al-dsp");
4502 break;
4503 case EF_SH3E:
4504 out = stpcpy (out, ", sh3e");
4505 break;
4506 case EF_SH4:
4507 out = stpcpy (out, ", sh4");
4508 break;
4509 case EF_SH5:
4510 out = stpcpy (out, ", sh5");
4511 break;
4512 case EF_SH2E:
4513 out = stpcpy (out, ", sh2e");
4514 break;
4515 case EF_SH4A:
4516 out = stpcpy (out, ", sh4a");
4517 break;
4518 case EF_SH2A:
4519 out = stpcpy (out, ", sh2a");
4520 break;
4521 case EF_SH4_NOFPU:
4522 out = stpcpy (out, ", sh4-nofpu");
4523 break;
4524 case EF_SH4A_NOFPU:
4525 out = stpcpy (out, ", sh4a-nofpu");
4526 break;
4527 case EF_SH2A_NOFPU:
4528 out = stpcpy (out, ", sh2a-nofpu");
4529 break;
4530 case EF_SH3_NOMMU:
4531 out = stpcpy (out, ", sh3-nommu");
4532 break;
4533 case EF_SH4_NOMMU_NOFPU:
4534 out = stpcpy (out, ", sh4-nommu-nofpu");
4535 break;
4536 case EF_SH2A_SH4_NOFPU:
4537 out = stpcpy (out, ", sh2a-nofpu-or-sh4-nommu-nofpu");
4538 break;
4539 case EF_SH2A_SH3_NOFPU:
4540 out = stpcpy (out, ", sh2a-nofpu-or-sh3-nommu");
4541 break;
4542 case EF_SH2A_SH4:
4543 out = stpcpy (out, ", sh2a-or-sh4");
4544 break;
4545 case EF_SH2A_SH3E:
4546 out = stpcpy (out, ", sh2a-or-sh3e");
4547 break;
4548 default:
4549 out = stpcpy (out, _(", unknown ISA"));
4550 break;
4553 if (e_flags & EF_SH_PIC)
4554 out = stpcpy (out, ", pic");
4556 if (e_flags & EF_SH_FDPIC)
4557 out = stpcpy (out, ", fdpic");
4558 return out;
4561 static char *
4562 decode_SPARC_machine_flags (char *out, unsigned e_flags)
4564 if (e_flags & EF_SPARC_32PLUS)
4565 out = stpcpy (out, ", v8+");
4567 if (e_flags & EF_SPARC_SUN_US1)
4568 out = stpcpy (out, ", ultrasparcI");
4570 if (e_flags & EF_SPARC_SUN_US3)
4571 out = stpcpy (out, ", ultrasparcIII");
4573 if (e_flags & EF_SPARC_HAL_R1)
4574 out = stpcpy (out, ", halr1");
4576 if (e_flags & EF_SPARC_LEDATA)
4577 out = stpcpy (out, ", ledata");
4579 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4580 out = stpcpy (out, ", tso");
4582 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4583 out = stpcpy (out, ", pso");
4585 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4586 out = stpcpy (out, ", rmo");
4587 return out;
4590 static char *
4591 decode_V800_machine_flags (char *out, unsigned int e_flags)
4593 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
4594 out = stpcpy (out, ", RH850 ABI");
4596 if (e_flags & EF_V800_850E3)
4597 out = stpcpy (out, ", V3 architecture");
4599 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
4600 out = stpcpy (out, ", FPU not used");
4602 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
4603 out = stpcpy (out, ", regmode: COMMON");
4605 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
4606 out = stpcpy (out, ", r4 not used");
4608 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
4609 out = stpcpy (out, ", r30 not used");
4611 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
4612 out = stpcpy (out, ", r5 not used");
4614 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
4615 out = stpcpy (out, ", r2 not used");
4617 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
4619 switch (e_flags & - e_flags)
4621 case EF_RH850_FPU_DOUBLE:
4622 out = stpcpy (out, ", double precision FPU");
4623 break;
4624 case EF_RH850_FPU_SINGLE:
4625 out = stpcpy (out, ", single precision FPU");
4626 break;
4627 case EF_RH850_REGMODE22:
4628 out = stpcpy (out, ", regmode:22");
4629 break;
4630 case EF_RH850_REGMODE32:
4631 out = stpcpy (out, ", regmode:23");
4632 break;
4633 case EF_RH850_GP_FIX:
4634 out = stpcpy (out, ", r4 fixed");
4635 break;
4636 case EF_RH850_GP_NOFIX:
4637 out = stpcpy (out, ", r4 free");
4638 break;
4639 case EF_RH850_EP_FIX:
4640 out = stpcpy (out, ", r30 fixed");
4641 break;
4642 case EF_RH850_EP_NOFIX:
4643 out = stpcpy (out, ", r30 free");
4644 break;
4645 case EF_RH850_TP_FIX:
4646 out = stpcpy (out, ", r5 fixed");
4647 break;
4648 case EF_RH850_TP_NOFIX:
4649 out = stpcpy (out, ", r5 free");
4650 break;
4651 case EF_RH850_REG2_RESERVE:
4652 out = stpcpy (out, ", r2 fixed");
4653 break;
4654 case EF_RH850_REG2_NORESERVE:
4655 out = stpcpy (out, ", r2 free");
4656 break;
4657 default:
4658 break;
4661 return out;
4664 static char *
4665 decode_V850_machine_flags (char *out, unsigned int e_flags)
4667 switch (e_flags & EF_V850_ARCH)
4669 case E_V850E3V5_ARCH:
4670 out = stpcpy (out, ", v850e3v5");
4671 break;
4672 case E_V850E2V3_ARCH:
4673 out = stpcpy (out, ", v850e2v3");
4674 break;
4675 case E_V850E2_ARCH:
4676 out = stpcpy (out, ", v850e2");
4677 break;
4678 case E_V850E1_ARCH:
4679 out = stpcpy (out, ", v850e1");
4680 break;
4681 case E_V850E_ARCH:
4682 out = stpcpy (out, ", v850e");
4683 break;
4684 case E_V850_ARCH:
4685 out = stpcpy (out, ", v850");
4686 break;
4687 default:
4688 out = stpcpy (out, _(", unknown v850 architecture variant"));
4689 break;
4691 return out;
4694 static char *
4695 decode_Z80_machine_flags (char *out, unsigned int e_flags)
4697 switch (e_flags & EF_Z80_MACH_MSK)
4699 case EF_Z80_MACH_Z80:
4700 out = stpcpy (out, ", Z80");
4701 break;
4702 case EF_Z80_MACH_Z180:
4703 out = stpcpy (out, ", Z180");
4704 break;
4705 case EF_Z80_MACH_R800:
4706 out = stpcpy (out, ", R800");
4707 break;
4708 case EF_Z80_MACH_EZ80_Z80:
4709 out = stpcpy (out, ", EZ80");
4710 break;
4711 case EF_Z80_MACH_EZ80_ADL:
4712 out = stpcpy (out, ", EZ80, ADL");
4713 break;
4714 case EF_Z80_MACH_GBZ80:
4715 out = stpcpy (out, ", GBZ80");
4716 break;
4717 case EF_Z80_MACH_Z80N:
4718 out = stpcpy (out, ", Z80N");
4719 break;
4720 default:
4721 out = stpcpy (out, _(", unknown"));
4722 break;
4724 return out;
4727 static char *
4728 decode_AMDGPU_machine_flags (char *out, unsigned int e_flags, Filedata *filedata)
4730 unsigned char *e_ident = filedata->file_header.e_ident;
4731 unsigned char osabi = e_ident[EI_OSABI];
4732 unsigned char abiversion = e_ident[EI_ABIVERSION];
4733 unsigned int mach;
4735 /* HSA OS ABI v2 used a different encoding, but we don't need to support it,
4736 it has been deprecated for a while.
4738 The PAL, MESA3D and NONE OS ABIs are not properly versioned, at the time
4739 of writing, they use the same flags as HSA v3, so the code below uses that
4740 assumption. */
4741 if (osabi == ELFOSABI_AMDGPU_HSA && abiversion < ELFABIVERSION_AMDGPU_HSA_V3)
4742 return out;
4744 mach = e_flags & EF_AMDGPU_MACH;
4745 switch (mach)
4747 #define AMDGPU_CASE(code, string) \
4748 case code: out = stpcpy (out, ", " string); break;
4749 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600")
4750 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601")
4751 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700")
4752 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701")
4753 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702")
4754 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703")
4755 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704")
4756 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801")
4757 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802")
4758 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803")
4759 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810")
4760 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900")
4761 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902")
4762 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904")
4763 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906")
4764 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908")
4765 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909")
4766 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c")
4767 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010")
4768 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011")
4769 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012")
4770 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030")
4771 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031")
4772 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032")
4773 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033")
4774 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1100, "gfx1100")
4775 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1101, "gfx1101")
4776 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1102, "gfx1102")
4777 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602")
4778 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705")
4779 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805")
4780 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035")
4781 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034")
4782 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a")
4783 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940")
4784 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013")
4785 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036")
4786 default:
4787 out += sprintf (out, _(", <unknown AMDGPU GPU type: %#x>"), mach);
4788 break;
4789 #undef AMDGPU_CASE
4792 e_flags &= ~EF_AMDGPU_MACH;
4794 if ((osabi == ELFOSABI_AMDGPU_HSA
4795 && abiversion == ELFABIVERSION_AMDGPU_HSA_V3)
4796 || osabi != ELFOSABI_AMDGPU_HSA)
4798 /* For HSA v3 and other OS ABIs. */
4799 if (e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
4801 out = stpcpy (out, ", xnack on");
4802 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V3;
4805 if (e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
4807 out = stpcpy (out, ", sramecc on");
4808 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V3;
4811 else
4813 /* For HSA v4+. */
4814 int xnack, sramecc;
4816 xnack = e_flags & EF_AMDGPU_FEATURE_XNACK_V4;
4817 switch (xnack)
4819 case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
4820 break;
4822 case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
4823 out = stpcpy (out, ", xnack any");
4824 break;
4826 case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
4827 out = stpcpy (out, ", xnack off");
4828 break;
4830 case EF_AMDGPU_FEATURE_XNACK_ON_V4:
4831 out = stpcpy (out, ", xnack on");
4832 break;
4834 default:
4835 out += sprintf (out, _(", <unknown xnack value: %#x>"), xnack);
4836 break;
4839 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V4;
4841 sramecc = e_flags & EF_AMDGPU_FEATURE_SRAMECC_V4;
4842 switch (sramecc)
4844 case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
4845 break;
4847 case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
4848 out = stpcpy (out, ", sramecc any");
4849 break;
4851 case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
4852 out = stpcpy (out, ", sramecc off");
4853 break;
4855 case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
4856 out = stpcpy (out, ", sramecc on");
4857 break;
4859 default:
4860 out += sprintf (out, _(", <unknown sramecc value: %#x>"), sramecc);
4861 break;
4864 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V4;
4867 if (e_flags != 0)
4868 out += sprintf (out, _(", unknown flags bits: %#x"), e_flags);
4869 return out;
4872 static char *
4873 get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
4875 static char buf[1024];
4876 char *out = buf;
4878 buf[0] = '\0';
4880 if (e_flags)
4882 switch (e_machine)
4884 default:
4885 break;
4887 case EM_ARC_COMPACT3:
4888 out = stpcpy (out, ", HS5x");
4889 break;
4891 case EM_ARC_COMPACT3_64:
4892 out = stpcpy (out, ", HS6x");
4893 break;
4895 case EM_ARC_COMPACT2:
4896 case EM_ARC_COMPACT:
4897 out = decode_ARC_machine_flags (out, e_flags, e_machine);
4898 break;
4900 case EM_ARM:
4901 out = decode_ARM_machine_flags (out, e_flags);
4902 break;
4904 case EM_AVR:
4905 out = decode_AVR_machine_flags (out, e_flags);
4906 break;
4908 case EM_BLACKFIN:
4909 out = decode_BLACKFIN_machine_flags (out, e_flags);
4910 break;
4912 case EM_CYGNUS_FRV:
4913 out = decode_FRV_machine_flags (out, e_flags);
4914 break;
4916 case EM_68K:
4917 out = decode_M68K_machine_flags (out, e_flags);
4918 break;
4920 case EM_AMDGPU:
4921 out = decode_AMDGPU_machine_flags (out, e_flags, filedata);
4922 break;
4924 case EM_CYGNUS_MEP:
4925 out = decode_MeP_machine_flags (out, e_flags);
4926 break;
4928 case EM_PPC:
4929 if (e_flags & EF_PPC_EMB)
4930 out = stpcpy (out, ", emb");
4932 if (e_flags & EF_PPC_RELOCATABLE)
4933 out = stpcpy (out, _(", relocatable"));
4935 if (e_flags & EF_PPC_RELOCATABLE_LIB)
4936 out = stpcpy (out, _(", relocatable-lib"));
4937 break;
4939 case EM_PPC64:
4940 if (e_flags & EF_PPC64_ABI)
4941 out += sprintf (out, ", abiv%d", e_flags & EF_PPC64_ABI);
4942 break;
4944 case EM_V800:
4945 out = decode_V800_machine_flags (out, e_flags);
4946 break;
4948 case EM_V850:
4949 case EM_CYGNUS_V850:
4950 out = decode_V850_machine_flags (out, e_flags);
4951 break;
4953 case EM_M32R:
4954 case EM_CYGNUS_M32R:
4955 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
4956 out = stpcpy (out, ", m32r");
4957 break;
4959 case EM_MIPS:
4960 case EM_MIPS_RS3_LE:
4961 out = decode_MIPS_machine_flags (out, e_flags);
4962 break;
4964 case EM_NDS32:
4965 out = decode_NDS32_machine_flags (out, e_flags);
4966 break;
4968 case EM_NFP:
4969 switch (EF_NFP_MACH (e_flags))
4971 case E_NFP_MACH_3200:
4972 out = stpcpy (out, ", NFP-32xx");
4973 break;
4974 case E_NFP_MACH_6000:
4975 out = stpcpy (out, ", NFP-6xxx");
4976 break;
4978 break;
4980 case EM_RISCV:
4981 out = decode_RISCV_machine_flags (out, e_flags);
4982 break;
4984 case EM_SH:
4985 out = decode_SH_machine_flags (out, e_flags);
4986 break;
4988 case EM_OR1K:
4989 if (e_flags & EF_OR1K_NODELAY)
4990 out = stpcpy (out, ", no delay");
4991 break;
4993 case EM_BPF:
4994 out += sprintf (out, ", CPU Version: %u", e_flags & EF_BPF_CPUVER);
4995 break;
4997 case EM_SPARCV9:
4998 out = decode_SPARC_machine_flags (out, e_flags);
4999 break;
5001 case EM_PARISC:
5002 out = decode_PARISC_machine_flags (out, e_flags);
5003 break;
5005 case EM_PJ:
5006 case EM_PJ_OLD:
5007 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
5008 out = stpcpy (out, ", new calling convention");
5010 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
5011 out = stpcpy (out, ", gnu calling convention");
5012 break;
5014 case EM_IA_64:
5015 out = decode_IA64_machine_flags (out, e_flags, filedata);
5016 break;
5018 case EM_VAX:
5019 if ((e_flags & EF_VAX_NONPIC))
5020 out = stpcpy (out, ", non-PIC");
5021 if ((e_flags & EF_VAX_DFLOAT))
5022 out = stpcpy (out, ", D-Float");
5023 if ((e_flags & EF_VAX_GFLOAT))
5024 out = stpcpy (out, ", G-Float");
5025 break;
5027 case EM_VISIUM:
5028 if (e_flags & EF_VISIUM_ARCH_MCM)
5029 out = stpcpy (out, ", mcm");
5030 else if (e_flags & EF_VISIUM_ARCH_MCM24)
5031 out = stpcpy (out, ", mcm24");
5032 if (e_flags & EF_VISIUM_ARCH_GR6)
5033 out = stpcpy (out, ", gr6");
5034 break;
5036 case EM_RL78:
5037 out = decode_RL78_machine_flags (out, e_flags);
5038 break;
5040 case EM_RX:
5041 out = decode_RX_machine_flags (out, e_flags);
5042 break;
5044 case EM_S390:
5045 if (e_flags & EF_S390_HIGH_GPRS)
5046 out = stpcpy (out, ", highgprs");
5047 break;
5049 case EM_TI_C6000:
5050 if ((e_flags & EF_C6000_REL))
5051 out = stpcpy (out, ", relocatable module");
5052 break;
5054 case EM_KVX:
5055 if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV3_1)
5056 strcat (buf, ", Kalray VLIW kv3-1");
5057 else if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV3_2)
5058 strcat (buf, ", Kalray VLIW kv3-2");
5059 else if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV4_1)
5060 strcat (buf, ", Kalray VLIW kv4-1");
5061 else
5062 strcat (buf, ", unknown KVX MPPA");
5063 break;
5065 case EM_MSP430:
5066 out = decode_MSP430_machine_flags (out, e_flags);
5067 break;
5069 case EM_Z80:
5070 out = decode_Z80_machine_flags (out, e_flags);
5071 break;
5073 case EM_LOONGARCH:
5074 out = decode_LOONGARCH_machine_flags (out, e_flags);
5075 break;
5079 return buf;
5082 static const char *
5083 get_osabi_name (Filedata * filedata, unsigned int osabi)
5085 static char buff[32];
5087 switch (osabi)
5089 case ELFOSABI_NONE: return "UNIX - System V";
5090 case ELFOSABI_HPUX: return "UNIX - HP-UX";
5091 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
5092 case ELFOSABI_GNU: return "UNIX - GNU";
5093 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
5094 case ELFOSABI_AIX: return "UNIX - AIX";
5095 case ELFOSABI_IRIX: return "UNIX - IRIX";
5096 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
5097 case ELFOSABI_TRU64: return "UNIX - TRU64";
5098 case ELFOSABI_MODESTO: return "Novell - Modesto";
5099 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
5100 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
5101 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
5102 case ELFOSABI_AROS: return "AROS";
5103 case ELFOSABI_FENIXOS: return "FenixOS";
5104 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
5105 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
5106 default:
5107 if (osabi >= 64)
5108 switch (filedata->file_header.e_machine)
5110 case EM_AMDGPU:
5111 switch (osabi)
5113 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
5114 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
5115 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
5116 default:
5117 break;
5119 break;
5121 case EM_ARM:
5122 switch (osabi)
5124 case ELFOSABI_ARM: return "ARM";
5125 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
5126 default:
5127 break;
5129 break;
5131 case EM_MSP430:
5132 case EM_MSP430_OLD:
5133 case EM_VISIUM:
5134 switch (osabi)
5136 case ELFOSABI_STANDALONE: return _("Standalone App");
5137 default:
5138 break;
5140 break;
5142 case EM_TI_C6000:
5143 switch (osabi)
5145 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
5146 case ELFOSABI_C6000_LINUX: return "Linux C6000";
5147 default:
5148 break;
5150 break;
5152 default:
5153 break;
5155 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
5156 return buff;
5160 static const char *
5161 get_aarch64_segment_type (unsigned long type)
5163 switch (type)
5165 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
5166 case PT_AARCH64_MEMTAG_MTE: return "AARCH64_MEMTAG_MTE";
5167 default: return NULL;
5171 static const char *
5172 get_arm_segment_type (unsigned long type)
5174 switch (type)
5176 case PT_ARM_EXIDX: return "EXIDX";
5177 default: return NULL;
5181 static const char *
5182 get_s390_segment_type (unsigned long type)
5184 switch (type)
5186 case PT_S390_PGSTE: return "S390_PGSTE";
5187 default: return NULL;
5191 static const char *
5192 get_mips_segment_type (unsigned long type)
5194 switch (type)
5196 case PT_MIPS_REGINFO: return "REGINFO";
5197 case PT_MIPS_RTPROC: return "RTPROC";
5198 case PT_MIPS_OPTIONS: return "OPTIONS";
5199 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
5200 default: return NULL;
5204 static const char *
5205 get_parisc_segment_type (unsigned long type)
5207 switch (type)
5209 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
5210 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
5211 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
5212 default: return NULL;
5216 static const char *
5217 get_ia64_segment_type (unsigned long type)
5219 switch (type)
5221 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
5222 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
5223 default: return NULL;
5227 static const char *
5228 get_tic6x_segment_type (unsigned long type)
5230 switch (type)
5232 case PT_C6000_PHATTR: return "C6000_PHATTR";
5233 default: return NULL;
5237 static const char *
5238 get_riscv_segment_type (unsigned long type)
5240 switch (type)
5242 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5243 default: return NULL;
5247 static const char *
5248 get_hpux_segment_type (unsigned long type, unsigned e_machine)
5250 if (e_machine == EM_PARISC)
5251 switch (type)
5253 case PT_HP_TLS: return "HP_TLS";
5254 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
5255 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
5256 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
5257 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
5258 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
5259 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
5260 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
5261 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
5262 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
5263 case PT_HP_PARALLEL: return "HP_PARALLEL";
5264 case PT_HP_FASTBIND: return "HP_FASTBIND";
5265 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
5266 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
5267 case PT_HP_STACK: return "HP_STACK";
5268 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
5269 default: return NULL;
5272 if (e_machine == EM_IA_64)
5273 switch (type)
5275 case PT_HP_TLS: return "HP_TLS";
5276 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
5277 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
5278 case PT_IA_64_HP_STACK: return "HP_STACK";
5279 default: return NULL;
5282 return NULL;
5285 static const char *
5286 get_solaris_segment_type (unsigned long type)
5288 switch (type)
5290 case 0x6464e550: return "PT_SUNW_UNWIND";
5291 case 0x6474e550: return "PT_SUNW_EH_FRAME";
5292 case 0x6ffffff7: return "PT_LOSUNW";
5293 case 0x6ffffffa: return "PT_SUNWBSS";
5294 case 0x6ffffffb: return "PT_SUNWSTACK";
5295 case 0x6ffffffc: return "PT_SUNWDTRACE";
5296 case 0x6ffffffd: return "PT_SUNWCAP";
5297 case 0x6fffffff: return "PT_HISUNW";
5298 default: return NULL;
5302 static const char *
5303 get_segment_type (Filedata * filedata, unsigned long p_type)
5305 static char buff[32];
5307 switch (p_type)
5309 case PT_NULL: return "NULL";
5310 case PT_LOAD: return "LOAD";
5311 case PT_DYNAMIC: return "DYNAMIC";
5312 case PT_INTERP: return "INTERP";
5313 case PT_NOTE: return "NOTE";
5314 case PT_SHLIB: return "SHLIB";
5315 case PT_PHDR: return "PHDR";
5316 case PT_TLS: return "TLS";
5317 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
5318 case PT_GNU_STACK: return "GNU_STACK";
5319 case PT_GNU_RELRO: return "GNU_RELRO";
5320 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
5321 case PT_GNU_SFRAME: return "GNU_SFRAME";
5323 case PT_OPENBSD_MUTABLE: return "OPENBSD_MUTABLE";
5324 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
5325 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
5326 case PT_OPENBSD_NOBTCFI: return "OPENBSD_NOBTCFI";
5327 case PT_OPENBSD_SYSCALLS: return "OPENBSD_SYSCALLS";
5328 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
5330 default:
5331 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
5333 const char * result;
5335 switch (filedata->file_header.e_machine)
5337 case EM_AARCH64:
5338 result = get_aarch64_segment_type (p_type);
5339 break;
5340 case EM_ARM:
5341 result = get_arm_segment_type (p_type);
5342 break;
5343 case EM_MIPS:
5344 case EM_MIPS_RS3_LE:
5345 result = get_mips_segment_type (p_type);
5346 break;
5347 case EM_PARISC:
5348 result = get_parisc_segment_type (p_type);
5349 break;
5350 case EM_IA_64:
5351 result = get_ia64_segment_type (p_type);
5352 break;
5353 case EM_TI_C6000:
5354 result = get_tic6x_segment_type (p_type);
5355 break;
5356 case EM_S390:
5357 case EM_S390_OLD:
5358 result = get_s390_segment_type (p_type);
5359 break;
5360 case EM_RISCV:
5361 result = get_riscv_segment_type (p_type);
5362 break;
5363 default:
5364 result = NULL;
5365 break;
5368 if (result != NULL)
5369 return result;
5371 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
5373 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
5375 const char * result = NULL;
5377 switch (filedata->file_header.e_ident[EI_OSABI])
5379 case ELFOSABI_GNU:
5380 case ELFOSABI_FREEBSD:
5381 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
5383 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
5384 result = buff;
5386 break;
5387 case ELFOSABI_HPUX:
5388 result = get_hpux_segment_type (p_type,
5389 filedata->file_header.e_machine);
5390 break;
5391 case ELFOSABI_SOLARIS:
5392 result = get_solaris_segment_type (p_type);
5393 break;
5394 default:
5395 break;
5397 if (result != NULL)
5398 return result;
5400 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
5402 else
5403 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
5405 return buff;
5409 static const char *
5410 get_arc_section_type_name (unsigned int sh_type)
5412 switch (sh_type)
5414 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
5415 default:
5416 break;
5418 return NULL;
5421 static const char *
5422 get_mips_section_type_name (unsigned int sh_type)
5424 switch (sh_type)
5426 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
5427 case SHT_MIPS_MSYM: return "MIPS_MSYM";
5428 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
5429 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
5430 case SHT_MIPS_UCODE: return "MIPS_UCODE";
5431 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
5432 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
5433 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
5434 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
5435 case SHT_MIPS_RELD: return "MIPS_RELD";
5436 case SHT_MIPS_IFACE: return "MIPS_IFACE";
5437 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
5438 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
5439 case SHT_MIPS_SHDR: return "MIPS_SHDR";
5440 case SHT_MIPS_FDESC: return "MIPS_FDESC";
5441 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
5442 case SHT_MIPS_DENSE: return "MIPS_DENSE";
5443 case SHT_MIPS_PDESC: return "MIPS_PDESC";
5444 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
5445 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
5446 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
5447 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
5448 case SHT_MIPS_LINE: return "MIPS_LINE";
5449 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
5450 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
5451 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
5452 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
5453 case SHT_MIPS_DWARF: return "MIPS_DWARF";
5454 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
5455 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
5456 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
5457 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
5458 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
5459 case SHT_MIPS_XLATE: return "MIPS_XLATE";
5460 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
5461 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
5462 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
5463 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
5464 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
5465 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
5466 case SHT_MIPS_XHASH: return "MIPS_XHASH";
5467 default:
5468 break;
5470 return NULL;
5473 static const char *
5474 get_parisc_section_type_name (unsigned int sh_type)
5476 switch (sh_type)
5478 case SHT_PARISC_EXT: return "PARISC_EXT";
5479 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
5480 case SHT_PARISC_DOC: return "PARISC_DOC";
5481 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
5482 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
5483 case SHT_PARISC_STUBS: return "PARISC_STUBS";
5484 case SHT_PARISC_DLKM: return "PARISC_DLKM";
5485 default: return NULL;
5489 static const char *
5490 get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
5492 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
5493 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
5494 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
5496 switch (sh_type)
5498 case SHT_IA_64_EXT: return "IA_64_EXT";
5499 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
5500 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
5501 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
5502 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
5503 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
5504 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
5505 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
5506 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
5507 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
5508 default:
5509 break;
5511 return NULL;
5514 static const char *
5515 get_x86_64_section_type_name (unsigned int sh_type)
5517 switch (sh_type)
5519 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
5520 default: return NULL;
5524 static const char *
5525 get_aarch64_section_type_name (unsigned int sh_type)
5527 switch (sh_type)
5529 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
5530 default: return NULL;
5534 static const char *
5535 get_arm_section_type_name (unsigned int sh_type)
5537 switch (sh_type)
5539 case SHT_ARM_EXIDX: return "ARM_EXIDX";
5540 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
5541 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
5542 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
5543 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
5544 default: return NULL;
5548 static const char *
5549 get_tic6x_section_type_name (unsigned int sh_type)
5551 switch (sh_type)
5553 case SHT_C6000_UNWIND: return "C6000_UNWIND";
5554 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
5555 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
5556 case SHT_TI_ICODE: return "TI_ICODE";
5557 case SHT_TI_XREF: return "TI_XREF";
5558 case SHT_TI_HANDLER: return "TI_HANDLER";
5559 case SHT_TI_INITINFO: return "TI_INITINFO";
5560 case SHT_TI_PHATTRS: return "TI_PHATTRS";
5561 default: return NULL;
5565 static const char *
5566 get_msp430_section_type_name (unsigned int sh_type)
5568 switch (sh_type)
5570 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
5571 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
5572 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
5573 default: return NULL;
5577 static const char *
5578 get_nfp_section_type_name (unsigned int sh_type)
5580 switch (sh_type)
5582 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
5583 case SHT_NFP_INITREG: return "NFP_INITREG";
5584 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
5585 default: return NULL;
5589 static const char *
5590 get_v850_section_type_name (unsigned int sh_type)
5592 switch (sh_type)
5594 case SHT_V850_SCOMMON: return "V850 Small Common";
5595 case SHT_V850_TCOMMON: return "V850 Tiny Common";
5596 case SHT_V850_ZCOMMON: return "V850 Zero Common";
5597 case SHT_RENESAS_IOP: return "RENESAS IOP";
5598 case SHT_RENESAS_INFO: return "RENESAS INFO";
5599 default: return NULL;
5603 static const char *
5604 get_riscv_section_type_name (unsigned int sh_type)
5606 switch (sh_type)
5608 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5609 default: return NULL;
5613 static const char *
5614 get_csky_section_type_name (unsigned int sh_type)
5616 switch (sh_type)
5618 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
5619 default: return NULL;
5623 static const char *
5624 get_section_type_name (Filedata * filedata, unsigned int sh_type)
5626 static char buff[32];
5627 const char * result;
5629 switch (sh_type)
5631 case SHT_NULL: return "NULL";
5632 case SHT_PROGBITS: return "PROGBITS";
5633 case SHT_SYMTAB: return "SYMTAB";
5634 case SHT_STRTAB: return "STRTAB";
5635 case SHT_RELA: return "RELA";
5636 case SHT_HASH: return "HASH";
5637 case SHT_DYNAMIC: return "DYNAMIC";
5638 case SHT_NOTE: return "NOTE";
5639 case SHT_NOBITS: return "NOBITS";
5640 case SHT_REL: return "REL";
5641 case SHT_SHLIB: return "SHLIB";
5642 case SHT_DYNSYM: return "DYNSYM";
5643 /* 12 and 13 are not defined. */
5644 case SHT_INIT_ARRAY: return "INIT_ARRAY";
5645 case SHT_FINI_ARRAY: return "FINI_ARRAY";
5646 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
5647 case SHT_GROUP: return "GROUP";
5648 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
5649 case SHT_RELR: return "RELR";
5650 /* End of generic section types. */
5652 /* OS specific section types: */
5653 case SHT_GNU_verdef: return "VERDEF";
5654 case SHT_GNU_verneed: return "VERNEED";
5655 case SHT_GNU_versym: return "VERSYM";
5656 case SHT_GNU_INCREMENTAL_INPUTS: return "GNU_INCREMENTAL_INPUTS";
5657 case 0x6ffffff0: return "VERSYM";
5658 case SHT_GNU_ATTRIBUTES: return "GNU_ATTRIBUTES";
5659 case SHT_GNU_HASH: return "GNU_HASH";
5660 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
5661 case 0x6ffffffc: return "VERDEF";
5662 case 0x7ffffffd: return "AUXILIARY";
5663 case 0x7fffffff: return "FILTER";
5665 default:
5666 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
5668 switch (filedata->file_header.e_machine)
5670 case EM_ARC:
5671 case EM_ARC_COMPACT:
5672 case EM_ARC_COMPACT2:
5673 case EM_ARC_COMPACT3:
5674 case EM_ARC_COMPACT3_64:
5675 result = get_arc_section_type_name (sh_type);
5676 break;
5677 case EM_MIPS:
5678 case EM_MIPS_RS3_LE:
5679 result = get_mips_section_type_name (sh_type);
5680 break;
5681 case EM_PARISC:
5682 result = get_parisc_section_type_name (sh_type);
5683 break;
5684 case EM_IA_64:
5685 result = get_ia64_section_type_name (filedata, sh_type);
5686 break;
5687 case EM_X86_64:
5688 case EM_L1OM:
5689 case EM_K1OM:
5690 result = get_x86_64_section_type_name (sh_type);
5691 break;
5692 case EM_AARCH64:
5693 result = get_aarch64_section_type_name (sh_type);
5694 break;
5695 case EM_ARM:
5696 result = get_arm_section_type_name (sh_type);
5697 break;
5698 case EM_TI_C6000:
5699 result = get_tic6x_section_type_name (sh_type);
5700 break;
5701 case EM_MSP430:
5702 result = get_msp430_section_type_name (sh_type);
5703 break;
5704 case EM_NFP:
5705 result = get_nfp_section_type_name (sh_type);
5706 break;
5707 case EM_V800:
5708 case EM_V850:
5709 case EM_CYGNUS_V850:
5710 result = get_v850_section_type_name (sh_type);
5711 break;
5712 case EM_RISCV:
5713 result = get_riscv_section_type_name (sh_type);
5714 break;
5715 case EM_CSKY:
5716 result = get_csky_section_type_name (sh_type);
5717 break;
5718 default:
5719 result = NULL;
5720 break;
5723 if (result != NULL)
5724 return result;
5726 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
5728 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
5730 switch (filedata->file_header.e_machine)
5732 case EM_IA_64:
5733 result = get_ia64_section_type_name (filedata, sh_type);
5734 break;
5735 default:
5736 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
5737 result = get_solaris_section_type (sh_type);
5738 else
5740 switch (sh_type)
5742 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
5743 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
5744 case SHT_GNU_HASH: result = "GNU_HASH"; break;
5745 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
5746 default:
5747 result = NULL;
5748 break;
5751 break;
5754 if (result != NULL)
5755 return result;
5757 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
5759 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
5761 switch (filedata->file_header.e_machine)
5763 case EM_V800:
5764 case EM_V850:
5765 case EM_CYGNUS_V850:
5766 result = get_v850_section_type_name (sh_type);
5767 break;
5768 default:
5769 result = NULL;
5770 break;
5773 if (result != NULL)
5774 return result;
5776 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
5778 else
5779 /* This message is probably going to be displayed in a 15
5780 character wide field, so put the hex value first. */
5781 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
5783 return buff;
5787 enum long_option_values
5789 OPTION_DEBUG_DUMP = 512,
5790 OPTION_DYN_SYMS,
5791 OPTION_LTO_SYMS,
5792 OPTION_DWARF_DEPTH,
5793 OPTION_DWARF_START,
5794 OPTION_DWARF_CHECK,
5795 OPTION_CTF_DUMP,
5796 OPTION_CTF_PARENT,
5797 OPTION_CTF_SYMBOLS,
5798 OPTION_CTF_STRINGS,
5799 OPTION_SFRAME_DUMP,
5800 OPTION_WITH_SYMBOL_VERSIONS,
5801 OPTION_RECURSE_LIMIT,
5802 OPTION_NO_RECURSE_LIMIT,
5803 OPTION_NO_DEMANGLING,
5804 OPTION_NO_EXTRA_SYM_INFO,
5805 OPTION_SYM_BASE
5808 static struct option options[] =
5810 /* Note - This table is alpha-sorted on the 'val'
5811 field in order to make adding new options easier. */
5812 {"arch-specific", no_argument, 0, 'A'},
5813 {"all", no_argument, 0, 'a'},
5814 {"demangle", optional_argument, 0, 'C'},
5815 {"archive-index", no_argument, 0, 'c'},
5816 {"use-dynamic", no_argument, 0, 'D'},
5817 {"dynamic", no_argument, 0, 'd'},
5818 {"headers", no_argument, 0, 'e'},
5819 {"section-groups", no_argument, 0, 'g'},
5820 {"help", no_argument, 0, 'H'},
5821 {"file-header", no_argument, 0, 'h'},
5822 {"histogram", no_argument, 0, 'I'},
5823 {"display-section", required_argument, 0, 'j'},
5824 {"lint", no_argument, 0, 'L'},
5825 {"enable-checks", no_argument, 0, 'L'},
5826 {"program-headers", no_argument, 0, 'l'},
5827 {"segments", no_argument, 0, 'l'},
5828 {"full-section-name",no_argument, 0, 'N'},
5829 {"notes", no_argument, 0, 'n'},
5830 {"process-links", no_argument, 0, 'P'},
5831 {"string-dump", required_argument, 0, 'p'},
5832 {"relocated-dump", required_argument, 0, 'R'},
5833 {"relocs", no_argument, 0, 'r'},
5834 {"section-headers", no_argument, 0, 'S'},
5835 {"sections", no_argument, 0, 'S'},
5836 {"symbols", no_argument, 0, 's'},
5837 {"syms", no_argument, 0, 's'},
5838 {"silent-truncation",no_argument, 0, 'T'},
5839 {"section-details", no_argument, 0, 't'},
5840 {"unicode", required_argument, NULL, 'U'},
5841 {"unwind", no_argument, 0, 'u'},
5842 {"version-info", no_argument, 0, 'V'},
5843 {"version", no_argument, 0, 'v'},
5844 {"wide", no_argument, 0, 'W'},
5845 {"extra-sym-info", no_argument, 0, 'X'},
5846 {"hex-dump", required_argument, 0, 'x'},
5847 {"decompress", no_argument, 0, 'z'},
5849 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
5850 {"no-extra-sym-info",no_argument, 0, OPTION_NO_EXTRA_SYM_INFO},
5851 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5852 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5853 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5854 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
5855 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
5856 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
5857 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5858 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
5859 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
5860 #ifdef ENABLE_LIBCTF
5861 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
5862 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5863 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5864 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
5865 #endif
5866 {"sframe", optional_argument, 0, OPTION_SFRAME_DUMP},
5867 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
5869 {0, no_argument, 0, 0}
5872 static void
5873 usage (FILE * stream)
5875 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5876 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
5877 fprintf (stream, _(" Options are:\n"));
5878 fprintf (stream, _("\
5879 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5880 fprintf (stream, _("\
5881 -h --file-header Display the ELF file header\n"));
5882 fprintf (stream, _("\
5883 -l --program-headers Display the program headers\n"));
5884 fprintf (stream, _("\
5885 --segments An alias for --program-headers\n"));
5886 fprintf (stream, _("\
5887 -S --section-headers Display the sections' header\n"));
5888 fprintf (stream, _("\
5889 --sections An alias for --section-headers\n"));
5890 fprintf (stream, _("\
5891 -g --section-groups Display the section groups\n"));
5892 fprintf (stream, _("\
5893 -t --section-details Display the section details\n"));
5894 fprintf (stream, _("\
5895 -e --headers Equivalent to: -h -l -S\n"));
5896 fprintf (stream, _("\
5897 -s --syms Display the symbol table\n"));
5898 fprintf (stream, _("\
5899 --symbols An alias for --syms\n"));
5900 fprintf (stream, _("\
5901 --dyn-syms Display the dynamic symbol table\n"));
5902 fprintf (stream, _("\
5903 --lto-syms Display LTO symbol tables\n"));
5904 fprintf (stream, _("\
5905 --sym-base=[0|8|10|16] \n\
5906 Force base for symbol sizes. The options are \n\
5907 mixed (the default), octal, decimal, hexadecimal.\n"));
5908 fprintf (stream, _("\
5909 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5910 display_demangler_styles (stream, _("\
5911 STYLE can be "));
5912 fprintf (stream, _("\
5913 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5914 fprintf (stream, _("\
5915 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5916 fprintf (stream, _("\
5917 --no-recurse-limit Disable a demangling recursion limit\n"));
5918 fprintf (stream, _("\
5919 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5920 Display unicode characters as determined by the current locale\n\
5921 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5922 escape sequences, or treat them as invalid and display as\n\
5923 \"{hex sequences}\"\n"));
5924 fprintf (stream, _("\
5925 -X --extra-sym-info Display extra information when showing symbols\n"));
5926 fprintf (stream, _("\
5927 --no-extra-sym-info Do not display extra information when showing symbols (default)\n"));
5928 fprintf (stream, _("\
5929 -n --notes Display the contents of note sections (if present)\n"));
5930 fprintf (stream, _("\
5931 -r --relocs Display the relocations (if present)\n"));
5932 fprintf (stream, _("\
5933 -u --unwind Display the unwind info (if present)\n"));
5934 fprintf (stream, _("\
5935 -d --dynamic Display the dynamic section (if present)\n"));
5936 fprintf (stream, _("\
5937 -V --version-info Display the version sections (if present)\n"));
5938 fprintf (stream, _("\
5939 -A --arch-specific Display architecture specific information (if any)\n"));
5940 fprintf (stream, _("\
5941 -c --archive-index Display the symbol/file index in an archive\n"));
5942 fprintf (stream, _("\
5943 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5944 fprintf (stream, _("\
5945 -L --lint|--enable-checks\n\
5946 Display warning messages for possible problems\n"));
5947 fprintf (stream, _("\
5948 -x --hex-dump=<number|name>\n\
5949 Dump the contents of section <number|name> as bytes\n"));
5950 fprintf (stream, _("\
5951 -p --string-dump=<number|name>\n\
5952 Dump the contents of section <number|name> as strings\n"));
5953 fprintf (stream, _("\
5954 -R --relocated-dump=<number|name>\n\
5955 Dump the relocated contents of section <number|name>\n"));
5956 fprintf (stream, _("\
5957 -z --decompress Decompress section before dumping it\n"));
5958 fprintf (stream, _("\n\
5959 -j --display-section=<name|number>\n\
5960 Display the contents of the indicated section. Can be repeated\n"));
5961 fprintf (stream, _("\
5962 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5963 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5964 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5965 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5966 U/=trace_info]\n\
5967 Display the contents of DWARF debug sections\n"));
5968 fprintf (stream, _("\
5969 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5970 debuginfo files\n"));
5971 fprintf (stream, _("\
5972 -P --process-links Display the contents of non-debug sections in separate\n\
5973 debuginfo files. (Implies -wK)\n"));
5974 #if DEFAULT_FOR_FOLLOW_LINKS
5975 fprintf (stream, _("\
5976 -wK --debug-dump=follow-links\n\
5977 Follow links to separate debug info files (default)\n"));
5978 fprintf (stream, _("\
5979 -wN --debug-dump=no-follow-links\n\
5980 Do not follow links to separate debug info files\n"));
5981 #else
5982 fprintf (stream, _("\
5983 -wK --debug-dump=follow-links\n\
5984 Follow links to separate debug info files\n"));
5985 fprintf (stream, _("\
5986 -wN --debug-dump=no-follow-links\n\
5987 Do not follow links to separate debug info files\n\
5988 (default)\n"));
5989 #endif
5990 #if HAVE_LIBDEBUGINFOD
5991 fprintf (stream, _("\
5992 -wD --debug-dump=use-debuginfod\n\
5993 When following links, also query debuginfod servers (default)\n"));
5994 fprintf (stream, _("\
5995 -wE --debug-dump=do-not-use-debuginfod\n\
5996 When following links, do not query debuginfod servers\n"));
5997 #endif
5998 fprintf (stream, _("\
5999 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
6000 fprintf (stream, _("\
6001 --dwarf-start=N Display DIEs starting at offset N\n"));
6002 #ifdef ENABLE_LIBCTF
6003 fprintf (stream, _("\
6004 --ctf=<number|name> Display CTF info from section <number|name>\n"));
6005 fprintf (stream, _("\
6006 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
6007 fprintf (stream, _("\
6008 --ctf-symbols=<number|name>\n\
6009 Use section <number|name> as the CTF external symtab\n"));
6010 fprintf (stream, _("\
6011 --ctf-strings=<number|name>\n\
6012 Use section <number|name> as the CTF external strtab\n"));
6013 #endif
6014 fprintf (stream, _("\
6015 --sframe[=NAME] Display SFrame info from section NAME, (default '.sframe')\n"));
6017 #ifdef SUPPORT_DISASSEMBLY
6018 fprintf (stream, _("\
6019 -i --instruction-dump=<number|name>\n\
6020 Disassemble the contents of section <number|name>\n"));
6021 #endif
6022 fprintf (stream, _("\
6023 -I --histogram Display histogram of bucket list lengths\n"));
6024 fprintf (stream, _("\
6025 -W --wide Allow output width to exceed 80 characters\n"));
6026 fprintf (stream, _("\
6027 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
6028 fprintf (stream, _("\
6029 @<file> Read options from <file>\n"));
6030 fprintf (stream, _("\
6031 -H --help Display this information\n"));
6032 fprintf (stream, _("\
6033 -v --version Display the version number of readelf\n"));
6035 if (REPORT_BUGS_TO[0] && stream == stdout)
6036 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
6038 exit (stream == stdout ? 0 : 1);
6041 /* Record the fact that the user wants the contents of section number
6042 SECTION to be displayed using the method(s) encoded as flags bits
6043 in TYPE. Note, TYPE can be zero if we are creating the array for
6044 the first time. */
6046 static void
6047 request_dump_bynumber (struct dump_data *dumpdata,
6048 unsigned int section, dump_type type)
6050 if (section >= dumpdata->num_dump_sects)
6052 dump_type * new_dump_sects;
6054 new_dump_sects = (dump_type *) calloc (section + 1,
6055 sizeof (* new_dump_sects));
6057 if (new_dump_sects == NULL)
6058 error (_("Out of memory allocating dump request table.\n"));
6059 else
6061 if (dumpdata->dump_sects)
6063 /* Copy current flag settings. */
6064 memcpy (new_dump_sects, dumpdata->dump_sects,
6065 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
6067 free (dumpdata->dump_sects);
6070 dumpdata->dump_sects = new_dump_sects;
6071 dumpdata->num_dump_sects = section + 1;
6075 if (dumpdata->dump_sects)
6076 dumpdata->dump_sects[section] |= type;
6079 /* Request a dump by section name. */
6081 static void
6082 request_dump_byname (const char * section, dump_type type)
6084 struct dump_list_entry * new_request;
6086 new_request = (struct dump_list_entry *)
6087 malloc (sizeof (struct dump_list_entry));
6088 if (!new_request)
6089 error (_("Out of memory allocating dump request table.\n"));
6091 new_request->name = strdup (section);
6092 if (!new_request->name)
6093 error (_("Out of memory allocating dump request table.\n"));
6095 new_request->type = type;
6097 new_request->next = dump_sects_byname;
6098 dump_sects_byname = new_request;
6101 static inline void
6102 request_dump (struct dump_data *dumpdata, dump_type type)
6104 int section;
6105 char * cp;
6107 do_dump = true;
6108 section = strtoul (optarg, & cp, 0);
6110 if (! *cp && section >= 0)
6111 request_dump_bynumber (dumpdata, section, type);
6112 else
6113 request_dump_byname (optarg, type);
6116 static void
6117 parse_args (struct dump_data *dumpdata, int argc, char ** argv)
6119 int c;
6121 if (argc < 2)
6122 usage (stderr);
6124 while ((c = getopt_long
6125 (argc, argv, "ACDHILNPR:STU:VWXacdeghi:j:lnp:rstuvw::x:z", options, NULL)) != EOF)
6127 switch (c)
6129 case 0:
6130 /* Long options. */
6131 break;
6132 case 'H':
6133 usage (stdout);
6134 break;
6136 case 'a':
6137 do_syms = true;
6138 do_reloc = true;
6139 do_unwind = true;
6140 do_dynamic = true;
6141 do_header = true;
6142 do_sections = true;
6143 do_section_groups = true;
6144 do_segments = true;
6145 do_version = true;
6146 do_histogram = true;
6147 do_arch = true;
6148 do_notes = true;
6149 break;
6151 case 'g':
6152 do_section_groups = true;
6153 break;
6154 case 't':
6155 case 'N':
6156 do_sections = true;
6157 do_section_details = true;
6158 break;
6159 case 'e':
6160 do_header = true;
6161 do_sections = true;
6162 do_segments = true;
6163 break;
6164 case 'A':
6165 do_arch = true;
6166 break;
6167 case 'D':
6168 do_using_dynamic = true;
6169 break;
6170 case 'r':
6171 do_reloc = true;
6172 break;
6173 case 'u':
6174 do_unwind = true;
6175 break;
6176 case 'h':
6177 do_header = true;
6178 break;
6179 case 'l':
6180 do_segments = true;
6181 break;
6182 case 's':
6183 do_syms = true;
6184 break;
6185 case 'S':
6186 do_sections = true;
6187 break;
6188 case 'd':
6189 do_dynamic = true;
6190 break;
6191 case 'I':
6192 do_histogram = true;
6193 break;
6194 case 'n':
6195 do_notes = true;
6196 break;
6197 case 'c':
6198 do_archive_index = true;
6199 break;
6200 case 'L':
6201 do_checks = true;
6202 break;
6203 case 'P':
6204 process_links = true;
6205 do_follow_links = true;
6206 dump_any_debugging = true;
6207 break;
6208 case 'j':
6209 request_dump (dumpdata, AUTO_DUMP);
6210 break;
6211 case 'x':
6212 request_dump (dumpdata, HEX_DUMP);
6213 break;
6214 case 'p':
6215 request_dump (dumpdata, STRING_DUMP);
6216 break;
6217 case 'R':
6218 request_dump (dumpdata, RELOC_DUMP);
6219 break;
6220 case 'z':
6221 decompress_dumps = true;
6222 break;
6223 case 'w':
6224 if (optarg == NULL)
6226 do_debugging = true;
6227 do_dump = true;
6228 dump_any_debugging = true;
6229 dwarf_select_sections_all ();
6231 else
6233 do_debugging = false;
6234 if (dwarf_select_sections_by_letters (optarg))
6236 do_dump = true;
6237 dump_any_debugging = true;
6240 break;
6241 case OPTION_DEBUG_DUMP:
6242 if (optarg == NULL)
6244 do_dump = true;
6245 do_debugging = true;
6246 dump_any_debugging = true;
6247 dwarf_select_sections_all ();
6249 else
6251 do_debugging = false;
6252 if (dwarf_select_sections_by_names (optarg))
6254 do_dump = true;
6255 dump_any_debugging = true;
6258 break;
6259 case OPTION_DWARF_DEPTH:
6261 char *cp;
6263 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
6265 break;
6266 case OPTION_DWARF_START:
6268 char *cp;
6270 dwarf_start_die = strtoul (optarg, & cp, 0);
6272 break;
6273 case OPTION_DWARF_CHECK:
6274 dwarf_check = true;
6275 break;
6276 case OPTION_CTF_DUMP:
6277 do_ctf = true;
6278 request_dump (dumpdata, CTF_DUMP);
6279 break;
6280 case OPTION_CTF_SYMBOLS:
6281 free (dump_ctf_symtab_name);
6282 dump_ctf_symtab_name = strdup (optarg);
6283 break;
6284 case OPTION_CTF_STRINGS:
6285 free (dump_ctf_strtab_name);
6286 dump_ctf_strtab_name = strdup (optarg);
6287 break;
6288 case OPTION_CTF_PARENT:
6289 free (dump_ctf_parent_name);
6290 dump_ctf_parent_name = strdup (optarg);
6291 break;
6292 case OPTION_SFRAME_DUMP:
6293 do_sframe = true;
6294 /* Providing section name is optional. request_dump (), however,
6295 thrives on non NULL optarg. Handle it explicitly here. */
6296 if (optarg != NULL)
6297 request_dump (dumpdata, SFRAME_DUMP);
6298 else
6300 do_dump = true;
6301 const char *sframe_sec_name = strdup (".sframe");
6302 request_dump_byname (sframe_sec_name, SFRAME_DUMP);
6304 break;
6305 case OPTION_DYN_SYMS:
6306 do_dyn_syms = true;
6307 break;
6308 case OPTION_LTO_SYMS:
6309 do_lto_syms = true;
6310 break;
6311 case 'X':
6312 extra_sym_info = true;
6313 break;
6314 case OPTION_NO_EXTRA_SYM_INFO:
6315 extra_sym_info = false;
6316 break;
6318 #ifdef SUPPORT_DISASSEMBLY
6319 case 'i':
6320 request_dump (dumpdata, DISASS_DUMP);
6321 break;
6322 #endif
6323 case 'v':
6324 print_version (program_name);
6325 break;
6326 case 'V':
6327 do_version = true;
6328 break;
6329 case 'W':
6330 do_wide = true;
6331 break;
6332 case 'T':
6333 do_not_show_symbol_truncation = true;
6334 break;
6335 case 'C':
6336 do_demangle = true;
6337 if (optarg != NULL)
6339 enum demangling_styles style;
6341 style = cplus_demangle_name_to_style (optarg);
6342 if (style == unknown_demangling)
6343 error (_("unknown demangling style `%s'"), optarg);
6345 cplus_demangle_set_style (style);
6347 break;
6348 case OPTION_NO_DEMANGLING:
6349 do_demangle = false;
6350 break;
6351 case OPTION_RECURSE_LIMIT:
6352 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
6353 break;
6354 case OPTION_NO_RECURSE_LIMIT:
6355 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
6356 break;
6357 case OPTION_WITH_SYMBOL_VERSIONS:
6358 /* Ignored for backward compatibility. */
6359 break;
6361 case 'U':
6362 if (optarg == NULL)
6363 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
6364 else if (streq (optarg, "default") || streq (optarg, "d"))
6365 unicode_display = unicode_default;
6366 else if (streq (optarg, "locale") || streq (optarg, "l"))
6367 unicode_display = unicode_locale;
6368 else if (streq (optarg, "escape") || streq (optarg, "e"))
6369 unicode_display = unicode_escape;
6370 else if (streq (optarg, "invalid") || streq (optarg, "i"))
6371 unicode_display = unicode_invalid;
6372 else if (streq (optarg, "hex") || streq (optarg, "x"))
6373 unicode_display = unicode_hex;
6374 else if (streq (optarg, "highlight") || streq (optarg, "h"))
6375 unicode_display = unicode_highlight;
6376 else
6377 error (_("invalid argument to -U/--unicode: %s"), optarg);
6378 break;
6380 case OPTION_SYM_BASE:
6381 sym_base = 0;
6382 if (optarg != NULL)
6384 sym_base = strtoul (optarg, NULL, 0);
6385 switch (sym_base)
6387 case 0:
6388 case 8:
6389 case 10:
6390 case 16:
6391 break;
6393 default:
6394 sym_base = 0;
6395 break;
6398 break;
6400 default:
6401 /* xgettext:c-format */
6402 error (_("Invalid option '-%c'\n"), c);
6403 /* Fall through. */
6404 case '?':
6405 usage (stderr);
6409 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
6410 && !do_segments && !do_header && !do_dump && !do_version
6411 && !do_histogram && !do_debugging && !do_arch && !do_notes
6412 && !do_section_groups && !do_archive_index
6413 && !do_dyn_syms && !do_lto_syms)
6415 if (do_checks)
6417 check_all = true;
6418 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
6419 do_segments = do_header = do_dump = do_version = true;
6420 do_histogram = do_debugging = do_arch = do_notes = true;
6421 do_section_groups = do_archive_index = do_dyn_syms = true;
6422 do_lto_syms = true;
6424 else
6425 usage (stderr);
6429 static const char *
6430 get_elf_class (unsigned int elf_class)
6432 static char buff[32];
6434 switch (elf_class)
6436 case ELFCLASSNONE: return _("none");
6437 case ELFCLASS32: return "ELF32";
6438 case ELFCLASS64: return "ELF64";
6439 default:
6440 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
6441 return buff;
6445 static const char *
6446 get_data_encoding (unsigned int encoding)
6448 static char buff[32];
6450 switch (encoding)
6452 case ELFDATANONE: return _("none");
6453 case ELFDATA2LSB: return _("2's complement, little endian");
6454 case ELFDATA2MSB: return _("2's complement, big endian");
6455 default:
6456 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
6457 return buff;
6461 static bool
6462 check_magic_number (Filedata * filedata, Elf_Internal_Ehdr * header)
6464 if (header->e_ident[EI_MAG0] == ELFMAG0
6465 && header->e_ident[EI_MAG1] == ELFMAG1
6466 && header->e_ident[EI_MAG2] == ELFMAG2
6467 && header->e_ident[EI_MAG3] == ELFMAG3)
6468 return true;
6470 /* Some compilers produce object files that are not in the ELF file format.
6471 As an aid to users of readelf, try to identify these cases and suggest
6472 alternative tools.
6474 FIXME: It is not clear if all four bytes are used as constant magic
6475 valus by all compilers. It may be necessary to recode this function if
6476 different tools use different length sequences. */
6478 static struct
6480 unsigned char magic[4];
6481 const char * obj_message;
6482 const char * ar_message;
6484 known_magic[] =
6486 { { 'B', 'C', 0xc0, 0xde },
6487 N_("This is a LLVM bitcode file - try using llvm-bcanalyzer\n"),
6488 N_("This is a LLVM bitcode file - try extracting and then using llvm-bcanalyzer\n")
6490 { { 'g', 'o', ' ', 'o' },
6491 N_("This is a GO binary file - try using 'go tool objdump' or 'go tool nm'\n"),
6492 NULL
6495 int i;
6497 for (i = ARRAY_SIZE (known_magic); i--;)
6499 if (header->e_ident[EI_MAG0] == known_magic[i].magic[0]
6500 && header->e_ident[EI_MAG1] == known_magic[i].magic[1]
6501 && header->e_ident[EI_MAG2] == known_magic[i].magic[2]
6502 && header->e_ident[EI_MAG3] == known_magic[i].magic[3])
6504 /* Some compiler's analyzer tools do not handle archives,
6505 so we provide two different kinds of error message. */
6506 if (filedata->archive_file_size > 0
6507 && known_magic[i].ar_message != NULL)
6508 error ("%s", known_magic[i].ar_message);
6509 else
6510 error ("%s", known_magic[i].obj_message);
6511 return false;
6515 error (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
6516 return false;
6519 /* Decode the data held in 'filedata->file_header'. */
6521 static bool
6522 process_file_header (Filedata * filedata)
6524 Elf_Internal_Ehdr * header = & filedata->file_header;
6526 if (! check_magic_number (filedata, header))
6527 return false;
6529 if (! filedata->is_separate)
6530 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
6532 if (do_header)
6534 unsigned i;
6536 if (filedata->is_separate)
6537 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
6538 else
6539 printf (_("ELF Header:\n"));
6540 printf (_(" Magic: "));
6541 for (i = 0; i < EI_NIDENT; i++)
6542 printf ("%2.2x ", header->e_ident[i]);
6543 printf ("\n");
6544 printf (_(" Class: %s\n"),
6545 get_elf_class (header->e_ident[EI_CLASS]));
6546 printf (_(" Data: %s\n"),
6547 get_data_encoding (header->e_ident[EI_DATA]));
6548 printf (_(" Version: %d%s\n"),
6549 header->e_ident[EI_VERSION],
6550 (header->e_ident[EI_VERSION] == EV_CURRENT
6551 ? _(" (current)")
6552 : (header->e_ident[EI_VERSION] != EV_NONE
6553 ? _(" <unknown>")
6554 : "")));
6555 printf (_(" OS/ABI: %s\n"),
6556 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
6557 printf (_(" ABI Version: %d\n"),
6558 header->e_ident[EI_ABIVERSION]);
6559 printf (_(" Type: %s\n"),
6560 get_file_type (filedata));
6561 printf (_(" Machine: %s\n"),
6562 get_machine_name (header->e_machine));
6563 printf (_(" Version: 0x%lx\n"),
6564 header->e_version);
6566 printf (_(" Entry point address: "));
6567 print_vma (header->e_entry, PREFIX_HEX);
6568 printf (_("\n Start of program headers: "));
6569 print_vma (header->e_phoff, DEC);
6570 printf (_(" (bytes into file)\n Start of section headers: "));
6571 print_vma (header->e_shoff, DEC);
6572 printf (_(" (bytes into file)\n"));
6574 printf (_(" Flags: 0x%lx%s\n"),
6575 header->e_flags,
6576 get_machine_flags (filedata, header->e_flags, header->e_machine));
6577 printf (_(" Size of this header: %u (bytes)\n"),
6578 header->e_ehsize);
6579 printf (_(" Size of program headers: %u (bytes)\n"),
6580 header->e_phentsize);
6581 printf (_(" Number of program headers: %u"),
6582 header->e_phnum);
6583 if (filedata->section_headers != NULL
6584 && header->e_phnum == PN_XNUM
6585 && filedata->section_headers[0].sh_info != 0)
6586 printf (" (%u)", filedata->section_headers[0].sh_info);
6587 putc ('\n', stdout);
6588 printf (_(" Size of section headers: %u (bytes)\n"),
6589 header->e_shentsize);
6590 printf (_(" Number of section headers: %u"),
6591 header->e_shnum);
6592 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
6594 header->e_shnum = filedata->section_headers[0].sh_size;
6595 printf (" (%u)", header->e_shnum);
6597 putc ('\n', stdout);
6598 printf (_(" Section header string table index: %u"),
6599 header->e_shstrndx);
6600 if (filedata->section_headers != NULL
6601 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
6603 header->e_shstrndx = filedata->section_headers[0].sh_link;
6604 printf (" (%u)", header->e_shstrndx);
6606 if (header->e_shstrndx != SHN_UNDEF
6607 && header->e_shstrndx >= header->e_shnum)
6609 header->e_shstrndx = SHN_UNDEF;
6610 printf (_(" <corrupt: out of range>"));
6612 putc ('\n', stdout);
6615 if (filedata->section_headers != NULL)
6617 if (header->e_phnum == PN_XNUM
6618 && filedata->section_headers[0].sh_info != 0)
6620 /* Throw away any cached read of PN_XNUM headers. */
6621 free (filedata->program_headers);
6622 filedata->program_headers = NULL;
6623 header->e_phnum = filedata->section_headers[0].sh_info;
6625 if (header->e_shnum == SHN_UNDEF)
6626 header->e_shnum = filedata->section_headers[0].sh_size;
6627 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
6628 header->e_shstrndx = filedata->section_headers[0].sh_link;
6629 if (header->e_shstrndx >= header->e_shnum)
6630 header->e_shstrndx = SHN_UNDEF;
6633 return true;
6636 /* Read in the program headers from FILEDATA and store them in PHEADERS.
6637 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
6639 static bool
6640 get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
6642 Elf32_External_Phdr * phdrs;
6643 Elf32_External_Phdr * external;
6644 Elf_Internal_Phdr * internal;
6645 unsigned int i;
6646 unsigned int size = filedata->file_header.e_phentsize;
6647 unsigned int num = filedata->file_header.e_phnum;
6649 /* PR binutils/17531: Cope with unexpected section header sizes. */
6650 if (size == 0 || num == 0)
6651 return false;
6652 if (size < sizeof * phdrs)
6654 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
6655 return false;
6657 if (size > sizeof * phdrs)
6658 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
6660 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
6661 size, num, _("program headers"));
6662 if (phdrs == NULL)
6663 return false;
6665 for (i = 0, internal = pheaders, external = phdrs;
6666 i < filedata->file_header.e_phnum;
6667 i++, internal++, external++)
6669 internal->p_type = BYTE_GET (external->p_type);
6670 internal->p_offset = BYTE_GET (external->p_offset);
6671 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6672 internal->p_paddr = BYTE_GET (external->p_paddr);
6673 internal->p_filesz = BYTE_GET (external->p_filesz);
6674 internal->p_memsz = BYTE_GET (external->p_memsz);
6675 internal->p_flags = BYTE_GET (external->p_flags);
6676 internal->p_align = BYTE_GET (external->p_align);
6679 free (phdrs);
6680 return true;
6683 /* Read in the program headers from FILEDATA and store them in PHEADERS.
6684 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
6686 static bool
6687 get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
6689 Elf64_External_Phdr * phdrs;
6690 Elf64_External_Phdr * external;
6691 Elf_Internal_Phdr * internal;
6692 unsigned int i;
6693 unsigned int size = filedata->file_header.e_phentsize;
6694 unsigned int num = filedata->file_header.e_phnum;
6696 /* PR binutils/17531: Cope with unexpected section header sizes. */
6697 if (size == 0 || num == 0)
6698 return false;
6699 if (size < sizeof * phdrs)
6701 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
6702 return false;
6704 if (size > sizeof * phdrs)
6705 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
6707 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
6708 size, num, _("program headers"));
6709 if (!phdrs)
6710 return false;
6712 for (i = 0, internal = pheaders, external = phdrs;
6713 i < filedata->file_header.e_phnum;
6714 i++, internal++, external++)
6716 internal->p_type = BYTE_GET (external->p_type);
6717 internal->p_flags = BYTE_GET (external->p_flags);
6718 internal->p_offset = BYTE_GET (external->p_offset);
6719 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6720 internal->p_paddr = BYTE_GET (external->p_paddr);
6721 internal->p_filesz = BYTE_GET (external->p_filesz);
6722 internal->p_memsz = BYTE_GET (external->p_memsz);
6723 internal->p_align = BYTE_GET (external->p_align);
6726 free (phdrs);
6727 return true;
6730 /* Returns TRUE if the program headers were read into `program_headers'. */
6732 static bool
6733 get_program_headers (Filedata * filedata)
6735 Elf_Internal_Phdr * phdrs;
6737 /* Check cache of prior read. */
6738 if (filedata->program_headers != NULL)
6739 return true;
6741 /* Be kind to memory checkers by looking for
6742 e_phnum values which we know must be invalid. */
6743 if (filedata->file_header.e_phnum
6744 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
6745 >= filedata->file_size)
6747 error (_("Too many program headers - %#x - the file is not that big\n"),
6748 filedata->file_header.e_phnum);
6749 return false;
6752 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
6753 sizeof (Elf_Internal_Phdr));
6754 if (phdrs == NULL)
6756 error (_("Out of memory reading %u program headers\n"),
6757 filedata->file_header.e_phnum);
6758 return false;
6761 if (is_32bit_elf
6762 ? get_32bit_program_headers (filedata, phdrs)
6763 : get_64bit_program_headers (filedata, phdrs))
6765 filedata->program_headers = phdrs;
6766 return true;
6769 free (phdrs);
6770 return false;
6773 /* Print program header info and locate dynamic section. */
6775 static void
6776 process_program_headers (Filedata * filedata)
6778 Elf_Internal_Phdr * segment;
6779 unsigned int i;
6780 Elf_Internal_Phdr * previous_load = NULL;
6782 if (filedata->file_header.e_phnum == 0)
6784 /* PR binutils/12467. */
6785 if (filedata->file_header.e_phoff != 0)
6786 warn (_("possibly corrupt ELF header - it has a non-zero program"
6787 " header offset, but no program headers\n"));
6788 else if (do_segments)
6790 if (filedata->is_separate)
6791 printf (_("\nThere are no program headers in linked file '%s'.\n"),
6792 filedata->file_name);
6793 else
6794 printf (_("\nThere are no program headers in this file.\n"));
6796 goto no_headers;
6799 if (do_segments && !do_header)
6801 if (filedata->is_separate)
6802 printf ("\nIn linked file '%s' the ELF file type is %s\n",
6803 filedata->file_name, get_file_type (filedata));
6804 else
6805 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
6806 printf (_("Entry point 0x%" PRIx64 "\n"),
6807 filedata->file_header.e_entry);
6808 printf (ngettext ("There is %d program header,"
6809 " starting at offset %" PRIu64 "\n",
6810 "There are %d program headers,"
6811 " starting at offset %" PRIu64 "\n",
6812 filedata->file_header.e_phnum),
6813 filedata->file_header.e_phnum,
6814 filedata->file_header.e_phoff);
6817 if (! get_program_headers (filedata))
6818 goto no_headers;
6820 if (do_segments)
6822 if (filedata->file_header.e_phnum > 1)
6823 printf (_("\nProgram Headers:\n"));
6824 else
6825 printf (_("\nProgram Headers:\n"));
6827 if (is_32bit_elf)
6828 printf
6829 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
6830 else if (do_wide)
6831 printf
6832 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
6833 else
6835 printf
6836 (_(" Type Offset VirtAddr PhysAddr\n"));
6837 printf
6838 (_(" FileSiz MemSiz Flags Align\n"));
6842 uint64_t dynamic_addr = 0;
6843 uint64_t dynamic_size = 0;
6844 for (i = 0, segment = filedata->program_headers;
6845 i < filedata->file_header.e_phnum;
6846 i++, segment++)
6848 if (do_segments)
6850 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
6852 if (is_32bit_elf)
6854 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6855 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
6856 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
6857 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
6858 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
6859 printf ("%c%c%c ",
6860 (segment->p_flags & PF_R ? 'R' : ' '),
6861 (segment->p_flags & PF_W ? 'W' : ' '),
6862 (segment->p_flags & PF_X ? 'E' : ' '));
6863 printf ("%#lx", (unsigned long) segment->p_align);
6865 else if (do_wide)
6867 if ((unsigned long) segment->p_offset == segment->p_offset)
6868 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6869 else
6871 print_vma (segment->p_offset, FULL_HEX);
6872 putchar (' ');
6875 print_vma (segment->p_vaddr, FULL_HEX);
6876 putchar (' ');
6877 print_vma (segment->p_paddr, FULL_HEX);
6878 putchar (' ');
6880 if ((unsigned long) segment->p_filesz == segment->p_filesz)
6881 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
6882 else
6884 print_vma (segment->p_filesz, FULL_HEX);
6885 putchar (' ');
6888 if ((unsigned long) segment->p_memsz == segment->p_memsz)
6889 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
6890 else
6892 print_vma (segment->p_memsz, FULL_HEX);
6895 printf (" %c%c%c ",
6896 (segment->p_flags & PF_R ? 'R' : ' '),
6897 (segment->p_flags & PF_W ? 'W' : ' '),
6898 (segment->p_flags & PF_X ? 'E' : ' '));
6900 if ((unsigned long) segment->p_align == segment->p_align)
6901 printf ("%#lx", (unsigned long) segment->p_align);
6902 else
6904 print_vma (segment->p_align, PREFIX_HEX);
6907 else
6909 print_vma (segment->p_offset, FULL_HEX);
6910 putchar (' ');
6911 print_vma (segment->p_vaddr, FULL_HEX);
6912 putchar (' ');
6913 print_vma (segment->p_paddr, FULL_HEX);
6914 printf ("\n ");
6915 print_vma (segment->p_filesz, FULL_HEX);
6916 putchar (' ');
6917 print_vma (segment->p_memsz, FULL_HEX);
6918 printf (" %c%c%c ",
6919 (segment->p_flags & PF_R ? 'R' : ' '),
6920 (segment->p_flags & PF_W ? 'W' : ' '),
6921 (segment->p_flags & PF_X ? 'E' : ' '));
6922 print_vma (segment->p_align, PREFIX_HEX);
6925 putc ('\n', stdout);
6928 switch (segment->p_type)
6930 case PT_LOAD:
6931 #if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
6932 required by the ELF standard, several programs, including the Linux
6933 kernel, make use of non-ordered segments. */
6934 if (previous_load
6935 && previous_load->p_vaddr > segment->p_vaddr)
6936 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
6937 #endif
6938 if (segment->p_memsz < segment->p_filesz)
6939 error (_("the segment's file size is larger than its memory size\n"));
6940 previous_load = segment;
6941 break;
6943 case PT_PHDR:
6944 /* PR 20815 - Verify that the program header is loaded into memory. */
6945 if (i > 0 && previous_load != NULL)
6946 error (_("the PHDR segment must occur before any LOAD segment\n"));
6947 if (filedata->file_header.e_machine != EM_PARISC)
6949 unsigned int j;
6951 for (j = 1; j < filedata->file_header.e_phnum; j++)
6953 Elf_Internal_Phdr *load = filedata->program_headers + j;
6954 if (load->p_type == PT_LOAD
6955 && load->p_offset <= segment->p_offset
6956 && (load->p_offset + load->p_filesz
6957 >= segment->p_offset + segment->p_filesz)
6958 && load->p_vaddr <= segment->p_vaddr
6959 && (load->p_vaddr + load->p_filesz
6960 >= segment->p_vaddr + segment->p_filesz))
6961 break;
6963 if (j == filedata->file_header.e_phnum)
6964 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6966 break;
6968 case PT_DYNAMIC:
6969 if (dynamic_addr)
6970 error (_("more than one dynamic segment\n"));
6972 /* By default, assume that the .dynamic section is the first
6973 section in the DYNAMIC segment. */
6974 dynamic_addr = segment->p_offset;
6975 dynamic_size = segment->p_filesz;
6977 /* Try to locate the .dynamic section. If there is
6978 a section header table, we can easily locate it. */
6979 if (filedata->section_headers != NULL)
6981 Elf_Internal_Shdr * sec;
6983 sec = find_section (filedata, ".dynamic");
6984 if (sec == NULL || sec->sh_size == 0)
6986 /* A corresponding .dynamic section is expected, but on
6987 IA-64/OpenVMS it is OK for it to be missing. */
6988 if (!is_ia64_vms (filedata))
6989 error (_("no .dynamic section in the dynamic segment\n"));
6990 break;
6993 if (sec->sh_type == SHT_NOBITS)
6995 dynamic_addr = 0;
6996 dynamic_size = 0;
6997 break;
7000 dynamic_addr = sec->sh_offset;
7001 dynamic_size = sec->sh_size;
7003 /* The PT_DYNAMIC segment, which is used by the run-time
7004 loader, should exactly match the .dynamic section. */
7005 if (do_checks
7006 && (dynamic_addr != segment->p_offset
7007 || dynamic_size != segment->p_filesz))
7008 warn (_("\
7009 the .dynamic section is not the same as the dynamic segment\n"));
7012 /* PR binutils/17512: Avoid corrupt dynamic section info in the
7013 segment. Check this after matching against the section headers
7014 so we don't warn on debuginfo file (which have NOBITS .dynamic
7015 sections). */
7016 if (dynamic_addr > filedata->file_size
7017 || (dynamic_size > filedata->file_size - dynamic_addr))
7019 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
7020 dynamic_addr = 0;
7021 dynamic_size = 0;
7023 break;
7025 case PT_INTERP:
7026 if (segment->p_offset >= filedata->file_size
7027 || segment->p_filesz > filedata->file_size - segment->p_offset
7028 || segment->p_filesz - 1 >= (size_t) -2
7029 || fseek64 (filedata->handle,
7030 filedata->archive_file_offset + segment->p_offset,
7031 SEEK_SET))
7032 error (_("Unable to find program interpreter name\n"));
7033 else
7035 size_t len = segment->p_filesz;
7036 free (filedata->program_interpreter);
7037 filedata->program_interpreter = xmalloc (len + 1);
7038 len = fread (filedata->program_interpreter, 1, len,
7039 filedata->handle);
7040 filedata->program_interpreter[len] = 0;
7042 if (do_segments)
7043 printf (_(" [Requesting program interpreter: %s]\n"),
7044 filedata->program_interpreter);
7046 break;
7050 if (do_segments
7051 && filedata->section_headers != NULL
7052 && filedata->string_table != NULL)
7054 printf (_("\n Section to Segment mapping:\n"));
7055 printf (_(" Segment Sections...\n"));
7057 for (i = 0; i < filedata->file_header.e_phnum; i++)
7059 unsigned int j;
7060 Elf_Internal_Shdr * section;
7062 segment = filedata->program_headers + i;
7063 section = filedata->section_headers + 1;
7065 printf (" %2.2d ", i);
7067 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
7069 if (!ELF_TBSS_SPECIAL (section, segment)
7070 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
7071 printf ("%s ", printable_section_name (filedata, section));
7074 putc ('\n',stdout);
7078 filedata->dynamic_addr = dynamic_addr;
7079 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
7080 return;
7082 no_headers:
7083 filedata->dynamic_addr = 0;
7084 filedata->dynamic_size = 1;
7088 /* Find the file offset corresponding to VMA by using the program headers. */
7090 static int64_t
7091 offset_from_vma (Filedata * filedata, uint64_t vma, uint64_t size)
7093 Elf_Internal_Phdr * seg;
7095 if (! get_program_headers (filedata))
7097 warn (_("Cannot interpret virtual addresses without program headers.\n"));
7098 return (long) vma;
7101 for (seg = filedata->program_headers;
7102 seg < filedata->program_headers + filedata->file_header.e_phnum;
7103 ++seg)
7105 if (seg->p_type != PT_LOAD)
7106 continue;
7108 if (vma >= (seg->p_vaddr & -seg->p_align)
7109 && vma + size <= seg->p_vaddr + seg->p_filesz)
7110 return vma - seg->p_vaddr + seg->p_offset;
7113 warn (_("Virtual address %#" PRIx64
7114 " not located in any PT_LOAD segment.\n"), vma);
7115 return vma;
7119 /* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
7120 If PROBE is true, this is just a probe and we do not generate any error
7121 messages if the load fails. */
7123 static bool
7124 get_32bit_section_headers (Filedata * filedata, bool probe)
7126 Elf32_External_Shdr * shdrs;
7127 Elf_Internal_Shdr * internal;
7128 unsigned int i;
7129 unsigned int size = filedata->file_header.e_shentsize;
7130 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
7132 /* PR binutils/17531: Cope with unexpected section header sizes. */
7133 if (size == 0 || num == 0)
7134 return false;
7136 /* The section header cannot be at the start of the file - that is
7137 where the ELF file header is located. A file with absolutely no
7138 sections in it will use a shoff of 0. */
7139 if (filedata->file_header.e_shoff == 0)
7140 return false;
7142 if (size < sizeof * shdrs)
7144 if (! probe)
7145 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
7146 return false;
7148 if (!probe && size > sizeof * shdrs)
7149 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
7151 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
7152 size, num,
7153 probe ? NULL : _("section headers"));
7154 if (shdrs == NULL)
7155 return false;
7157 filedata->section_headers = (Elf_Internal_Shdr *)
7158 cmalloc (num, sizeof (Elf_Internal_Shdr));
7159 if (filedata->section_headers == NULL)
7161 if (!probe)
7162 error (_("Out of memory reading %u section headers\n"), num);
7163 free (shdrs);
7164 return false;
7167 for (i = 0, internal = filedata->section_headers;
7168 i < num;
7169 i++, internal++)
7171 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
7172 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
7173 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
7174 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
7175 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
7176 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
7177 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
7178 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
7179 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
7180 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
7181 if (!probe && internal->sh_link > num)
7182 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
7183 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
7184 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
7187 free (shdrs);
7188 return true;
7191 /* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
7193 static bool
7194 get_64bit_section_headers (Filedata * filedata, bool probe)
7196 Elf64_External_Shdr * shdrs;
7197 Elf_Internal_Shdr * internal;
7198 unsigned int i;
7199 unsigned int size = filedata->file_header.e_shentsize;
7200 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
7202 /* PR binutils/17531: Cope with unexpected section header sizes. */
7203 if (size == 0 || num == 0)
7204 return false;
7206 /* The section header cannot be at the start of the file - that is
7207 where the ELF file header is located. A file with absolutely no
7208 sections in it will use a shoff of 0. */
7209 if (filedata->file_header.e_shoff == 0)
7210 return false;
7212 if (size < sizeof * shdrs)
7214 if (! probe)
7215 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
7216 return false;
7219 if (! probe && size > sizeof * shdrs)
7220 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
7222 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
7223 filedata->file_header.e_shoff,
7224 size, num,
7225 probe ? NULL : _("section headers"));
7226 if (shdrs == NULL)
7227 return false;
7229 filedata->section_headers = (Elf_Internal_Shdr *)
7230 cmalloc (num, sizeof (Elf_Internal_Shdr));
7231 if (filedata->section_headers == NULL)
7233 if (! probe)
7234 error (_("Out of memory reading %u section headers\n"), num);
7235 free (shdrs);
7236 return false;
7239 for (i = 0, internal = filedata->section_headers;
7240 i < num;
7241 i++, internal++)
7243 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
7244 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
7245 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
7246 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
7247 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
7248 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
7249 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
7250 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
7251 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
7252 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
7253 if (!probe && internal->sh_link > num)
7254 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
7255 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
7256 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
7259 free (shdrs);
7260 return true;
7263 static bool
7264 get_section_headers (Filedata *filedata, bool probe)
7266 if (filedata->section_headers != NULL)
7267 return true;
7269 if (is_32bit_elf)
7270 return get_32bit_section_headers (filedata, probe);
7271 else
7272 return get_64bit_section_headers (filedata, probe);
7275 static Elf_Internal_Sym *
7276 get_32bit_elf_symbols (Filedata *filedata,
7277 Elf_Internal_Shdr *section,
7278 uint64_t *num_syms_return)
7280 uint64_t number = 0;
7281 Elf32_External_Sym * esyms = NULL;
7282 Elf_External_Sym_Shndx * shndx = NULL;
7283 Elf_Internal_Sym * isyms = NULL;
7284 Elf_Internal_Sym * psym;
7285 unsigned int j;
7286 elf_section_list * entry;
7288 if (section->sh_size == 0)
7290 if (num_syms_return != NULL)
7291 * num_syms_return = 0;
7292 return NULL;
7295 /* Run some sanity checks first. */
7296 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
7298 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
7299 printable_section_name (filedata, section),
7300 section->sh_entsize);
7301 goto exit_point;
7304 if (section->sh_size > filedata->file_size)
7306 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
7307 printable_section_name (filedata, section),
7308 section->sh_size);
7309 goto exit_point;
7312 number = section->sh_size / section->sh_entsize;
7314 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
7316 error (_("Size (%#" PRIx64 ") of section %s "
7317 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7318 section->sh_size,
7319 printable_section_name (filedata, section),
7320 section->sh_entsize);
7321 goto exit_point;
7324 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
7325 section->sh_size, _("symbols"));
7326 if (esyms == NULL)
7327 goto exit_point;
7329 shndx = NULL;
7330 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
7332 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
7333 continue;
7335 if (shndx != NULL)
7337 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7338 free (shndx);
7341 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7342 entry->hdr->sh_offset,
7343 1, entry->hdr->sh_size,
7344 _("symbol table section indices"));
7345 if (shndx == NULL)
7346 goto exit_point;
7348 /* PR17531: file: heap-buffer-overflow */
7349 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7351 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
7352 printable_section_name (filedata, entry->hdr),
7353 entry->hdr->sh_size,
7354 section->sh_size);
7355 goto exit_point;
7359 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
7361 if (isyms == NULL)
7363 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
7364 goto exit_point;
7367 for (j = 0, psym = isyms; j < number; j++, psym++)
7369 psym->st_name = BYTE_GET (esyms[j].st_name);
7370 psym->st_value = BYTE_GET (esyms[j].st_value);
7371 psym->st_size = BYTE_GET (esyms[j].st_size);
7372 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
7373 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
7374 psym->st_shndx
7375 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
7376 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7377 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
7378 psym->st_info = BYTE_GET (esyms[j].st_info);
7379 psym->st_other = BYTE_GET (esyms[j].st_other);
7382 exit_point:
7383 free (shndx);
7384 free (esyms);
7386 if (num_syms_return != NULL)
7387 * num_syms_return = isyms == NULL ? 0 : number;
7389 return isyms;
7392 static Elf_Internal_Sym *
7393 get_64bit_elf_symbols (Filedata *filedata,
7394 Elf_Internal_Shdr *section,
7395 uint64_t *num_syms_return)
7397 uint64_t number = 0;
7398 Elf64_External_Sym * esyms = NULL;
7399 Elf_External_Sym_Shndx * shndx = NULL;
7400 Elf_Internal_Sym * isyms = NULL;
7401 Elf_Internal_Sym * psym;
7402 unsigned int j;
7403 elf_section_list * entry;
7405 if (section->sh_size == 0)
7407 if (num_syms_return != NULL)
7408 * num_syms_return = 0;
7409 return NULL;
7412 /* Run some sanity checks first. */
7413 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
7415 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
7416 printable_section_name (filedata, section),
7417 section->sh_entsize);
7418 goto exit_point;
7421 if (section->sh_size > filedata->file_size)
7423 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
7424 printable_section_name (filedata, section),
7425 section->sh_size);
7426 goto exit_point;
7429 number = section->sh_size / section->sh_entsize;
7431 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
7433 error (_("Size (%#" PRIx64 ") of section %s "
7434 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7435 section->sh_size,
7436 printable_section_name (filedata, section),
7437 section->sh_entsize);
7438 goto exit_point;
7441 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
7442 section->sh_size, _("symbols"));
7443 if (!esyms)
7444 goto exit_point;
7446 shndx = NULL;
7447 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
7449 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
7450 continue;
7452 if (shndx != NULL)
7454 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7455 free (shndx);
7458 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7459 entry->hdr->sh_offset,
7460 1, entry->hdr->sh_size,
7461 _("symbol table section indices"));
7462 if (shndx == NULL)
7463 goto exit_point;
7465 /* PR17531: file: heap-buffer-overflow */
7466 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7468 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
7469 printable_section_name (filedata, entry->hdr),
7470 entry->hdr->sh_size,
7471 section->sh_size);
7472 goto exit_point;
7476 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
7478 if (isyms == NULL)
7480 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
7481 goto exit_point;
7484 for (j = 0, psym = isyms; j < number; j++, psym++)
7486 psym->st_name = BYTE_GET (esyms[j].st_name);
7487 psym->st_info = BYTE_GET (esyms[j].st_info);
7488 psym->st_other = BYTE_GET (esyms[j].st_other);
7489 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
7491 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
7492 psym->st_shndx
7493 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
7494 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7495 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
7497 psym->st_value = BYTE_GET (esyms[j].st_value);
7498 psym->st_size = BYTE_GET (esyms[j].st_size);
7501 exit_point:
7502 free (shndx);
7503 free (esyms);
7505 if (num_syms_return != NULL)
7506 * num_syms_return = isyms == NULL ? 0 : number;
7508 return isyms;
7511 static Elf_Internal_Sym *
7512 get_elf_symbols (Filedata *filedata,
7513 Elf_Internal_Shdr *section,
7514 uint64_t *num_syms_return)
7516 if (is_32bit_elf)
7517 return get_32bit_elf_symbols (filedata, section, num_syms_return);
7518 else
7519 return get_64bit_elf_symbols (filedata, section, num_syms_return);
7522 static const char *
7523 get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
7525 static char buff[1024];
7526 char * p = buff;
7527 unsigned int field_size = is_32bit_elf ? 8 : 16;
7528 signed int sindex;
7529 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
7530 uint64_t os_flags = 0;
7531 uint64_t proc_flags = 0;
7532 uint64_t unknown_flags = 0;
7533 static const struct
7535 const char * str;
7536 unsigned int len;
7538 flags [] =
7540 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
7541 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
7542 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
7543 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
7544 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
7545 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
7546 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
7547 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
7548 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
7549 /* 9 */ { STRING_COMMA_LEN ("TLS") },
7550 /* IA-64 specific. */
7551 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
7552 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
7553 /* IA-64 OpenVMS specific. */
7554 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
7555 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
7556 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
7557 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
7558 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
7559 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
7560 /* Generic. */
7561 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
7562 /* SPARC specific. */
7563 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
7564 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
7565 /* ARM specific. */
7566 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
7567 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
7568 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
7569 /* GNU specific. */
7570 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
7571 /* VLE specific. */
7572 /* 25 */ { STRING_COMMA_LEN ("VLE") },
7573 /* GNU specific. */
7574 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
7577 if (do_section_details)
7578 p += sprintf (p, "[%*.*lx]: ",
7579 field_size, field_size, (unsigned long) sh_flags);
7581 while (sh_flags)
7583 uint64_t flag;
7585 flag = sh_flags & - sh_flags;
7586 sh_flags &= ~ flag;
7588 if (do_section_details)
7590 switch (flag)
7592 case SHF_WRITE: sindex = 0; break;
7593 case SHF_ALLOC: sindex = 1; break;
7594 case SHF_EXECINSTR: sindex = 2; break;
7595 case SHF_MERGE: sindex = 3; break;
7596 case SHF_STRINGS: sindex = 4; break;
7597 case SHF_INFO_LINK: sindex = 5; break;
7598 case SHF_LINK_ORDER: sindex = 6; break;
7599 case SHF_OS_NONCONFORMING: sindex = 7; break;
7600 case SHF_GROUP: sindex = 8; break;
7601 case SHF_TLS: sindex = 9; break;
7602 case SHF_EXCLUDE: sindex = 18; break;
7603 case SHF_COMPRESSED: sindex = 20; break;
7605 default:
7606 sindex = -1;
7607 switch (filedata->file_header.e_machine)
7609 case EM_IA_64:
7610 if (flag == SHF_IA_64_SHORT)
7611 sindex = 10;
7612 else if (flag == SHF_IA_64_NORECOV)
7613 sindex = 11;
7614 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
7615 switch (flag)
7617 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
7618 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
7619 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
7620 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
7621 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
7622 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
7623 default: break;
7625 break;
7627 case EM_386:
7628 case EM_IAMCU:
7629 case EM_X86_64:
7630 case EM_L1OM:
7631 case EM_K1OM:
7632 case EM_OLD_SPARCV9:
7633 case EM_SPARC32PLUS:
7634 case EM_SPARCV9:
7635 case EM_SPARC:
7636 if (flag == SHF_ORDERED)
7637 sindex = 19;
7638 break;
7640 case EM_ARM:
7641 switch (flag)
7643 case SHF_ENTRYSECT: sindex = 21; break;
7644 case SHF_ARM_PURECODE: sindex = 22; break;
7645 case SHF_COMDEF: sindex = 23; break;
7646 default: break;
7648 break;
7649 case EM_PPC:
7650 if (flag == SHF_PPC_VLE)
7651 sindex = 25;
7652 break;
7653 default:
7654 break;
7657 switch (filedata->file_header.e_ident[EI_OSABI])
7659 case ELFOSABI_GNU:
7660 case ELFOSABI_FREEBSD:
7661 if (flag == SHF_GNU_RETAIN)
7662 sindex = 26;
7663 /* Fall through */
7664 case ELFOSABI_NONE:
7665 if (flag == SHF_GNU_MBIND)
7666 /* We should not recognize SHF_GNU_MBIND for
7667 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7668 not set the EI_OSABI header byte. */
7669 sindex = 24;
7670 break;
7671 default:
7672 break;
7674 break;
7677 if (sindex != -1)
7679 if (p != buff + field_size + 4)
7681 if (size < (10 + 2))
7683 warn (_("Internal error: not enough buffer room for section flag info"));
7684 return _("<unknown>");
7686 size -= 2;
7687 *p++ = ',';
7688 *p++ = ' ';
7691 size -= flags [sindex].len;
7692 p = stpcpy (p, flags [sindex].str);
7694 else if (flag & SHF_MASKOS)
7695 os_flags |= flag;
7696 else if (flag & SHF_MASKPROC)
7697 proc_flags |= flag;
7698 else
7699 unknown_flags |= flag;
7701 else
7703 switch (flag)
7705 case SHF_WRITE: *p = 'W'; break;
7706 case SHF_ALLOC: *p = 'A'; break;
7707 case SHF_EXECINSTR: *p = 'X'; break;
7708 case SHF_MERGE: *p = 'M'; break;
7709 case SHF_STRINGS: *p = 'S'; break;
7710 case SHF_INFO_LINK: *p = 'I'; break;
7711 case SHF_LINK_ORDER: *p = 'L'; break;
7712 case SHF_OS_NONCONFORMING: *p = 'O'; break;
7713 case SHF_GROUP: *p = 'G'; break;
7714 case SHF_TLS: *p = 'T'; break;
7715 case SHF_EXCLUDE: *p = 'E'; break;
7716 case SHF_COMPRESSED: *p = 'C'; break;
7718 default:
7719 if ((filedata->file_header.e_machine == EM_X86_64
7720 || filedata->file_header.e_machine == EM_L1OM
7721 || filedata->file_header.e_machine == EM_K1OM)
7722 && flag == SHF_X86_64_LARGE)
7723 *p = 'l';
7724 else if (filedata->file_header.e_machine == EM_ARM
7725 && flag == SHF_ARM_PURECODE)
7726 *p = 'y';
7727 else if (filedata->file_header.e_machine == EM_PPC
7728 && flag == SHF_PPC_VLE)
7729 *p = 'v';
7730 else if (flag & SHF_MASKOS)
7732 switch (filedata->file_header.e_ident[EI_OSABI])
7734 case ELFOSABI_GNU:
7735 case ELFOSABI_FREEBSD:
7736 if (flag == SHF_GNU_RETAIN)
7738 *p = 'R';
7739 break;
7741 /* Fall through */
7742 case ELFOSABI_NONE:
7743 if (flag == SHF_GNU_MBIND)
7745 /* We should not recognize SHF_GNU_MBIND for
7746 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7747 not set the EI_OSABI header byte. */
7748 *p = 'D';
7749 break;
7751 /* Fall through */
7752 default:
7753 *p = 'o';
7754 sh_flags &= ~SHF_MASKOS;
7755 break;
7758 else if (flag & SHF_MASKPROC)
7760 *p = 'p';
7761 sh_flags &= ~ SHF_MASKPROC;
7763 else
7764 *p = 'x';
7765 break;
7767 p++;
7771 if (do_section_details)
7773 if (os_flags)
7775 if (p != buff + field_size + 4)
7777 if (size < 2 + 5 + field_size + 1)
7779 warn (_("Internal error: not enough buffer room for section flag info"));
7780 return _("<unknown>");
7782 size -= 2;
7783 *p++ = ',';
7784 *p++ = ' ';
7786 size -= 5 + field_size;
7787 p += sprintf (p, "OS (%*.*lx)", field_size, field_size,
7788 (unsigned long) os_flags);
7790 if (proc_flags)
7792 if (p != buff + field_size + 4)
7794 if (size < 2 + 7 + field_size + 1)
7796 warn (_("Internal error: not enough buffer room for section flag info"));
7797 return _("<unknown>");
7799 size -= 2;
7800 *p++ = ',';
7801 *p++ = ' ';
7803 size -= 7 + field_size;
7804 p += sprintf (p, "PROC (%*.*lx)", field_size, field_size,
7805 (unsigned long) proc_flags);
7807 if (unknown_flags)
7809 if (p != buff + field_size + 4)
7811 if (size < 2 + 10 + field_size + 1)
7813 warn (_("Internal error: not enough buffer room for section flag info"));
7814 return _("<unknown>");
7816 size -= 2;
7817 *p++ = ',';
7818 *p++ = ' ';
7820 size -= 10 + field_size;
7821 p += sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
7822 (unsigned long) unknown_flags);
7826 *p = '\0';
7827 return buff;
7830 static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
7831 get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf,
7832 uint64_t size)
7834 if (is_32bit_elf)
7836 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
7838 if (size < sizeof (* echdr))
7840 error (_("Compressed section is too small even for a compression header\n"));
7841 return 0;
7844 chdr->ch_type = BYTE_GET (echdr->ch_type);
7845 chdr->ch_size = BYTE_GET (echdr->ch_size);
7846 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7847 return sizeof (*echdr);
7849 else
7851 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
7853 if (size < sizeof (* echdr))
7855 error (_("Compressed section is too small even for a compression header\n"));
7856 return 0;
7859 chdr->ch_type = BYTE_GET (echdr->ch_type);
7860 chdr->ch_size = BYTE_GET (echdr->ch_size);
7861 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7862 return sizeof (*echdr);
7866 static bool
7867 process_section_headers (Filedata * filedata)
7869 Elf_Internal_Shdr * section;
7870 unsigned int i;
7872 if (filedata->file_header.e_shnum == 0)
7874 /* PR binutils/12467. */
7875 if (filedata->file_header.e_shoff != 0)
7877 warn (_("possibly corrupt ELF file header - it has a non-zero"
7878 " section header offset, but no section headers\n"));
7879 return false;
7881 else if (do_sections)
7882 printf (_("\nThere are no sections in this file.\n"));
7884 return true;
7887 if (do_sections && !do_header)
7889 if (filedata->is_separate && process_links)
7890 printf (_("In linked file '%s': "), filedata->file_name);
7891 if (! filedata->is_separate || process_links)
7892 printf (ngettext ("There is %d section header, "
7893 "starting at offset %#" PRIx64 ":\n",
7894 "There are %d section headers, "
7895 "starting at offset %#" PRIx64 ":\n",
7896 filedata->file_header.e_shnum),
7897 filedata->file_header.e_shnum,
7898 filedata->file_header.e_shoff);
7901 if (!get_section_headers (filedata, false))
7902 return false;
7904 /* Read in the string table, so that we have names to display. */
7905 if (filedata->file_header.e_shstrndx != SHN_UNDEF
7906 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
7908 section = filedata->section_headers + filedata->file_header.e_shstrndx;
7910 if (section->sh_size != 0)
7912 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
7913 1, section->sh_size,
7914 _("string table"));
7916 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
7920 /* Scan the sections for the dynamic symbol table
7921 and dynamic string table and debug sections. */
7922 eh_addr_size = is_32bit_elf ? 4 : 8;
7923 switch (filedata->file_header.e_machine)
7925 case EM_MIPS:
7926 case EM_MIPS_RS3_LE:
7927 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
7928 FDE addresses. However, the ABI also has a semi-official ILP32
7929 variant for which the normal FDE address size rules apply.
7931 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
7932 section, where XX is the size of longs in bits. Unfortunately,
7933 earlier compilers provided no way of distinguishing ILP32 objects
7934 from LP64 objects, so if there's any doubt, we should assume that
7935 the official LP64 form is being used. */
7936 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == EF_MIPS_ABI_EABI64
7937 && find_section (filedata, ".gcc_compiled_long32") == NULL)
7938 eh_addr_size = 8;
7939 break;
7941 case EM_H8_300:
7942 case EM_H8_300H:
7943 switch (filedata->file_header.e_flags & EF_H8_MACH)
7945 case E_H8_MACH_H8300:
7946 case E_H8_MACH_H8300HN:
7947 case E_H8_MACH_H8300SN:
7948 case E_H8_MACH_H8300SXN:
7949 eh_addr_size = 2;
7950 break;
7951 case E_H8_MACH_H8300H:
7952 case E_H8_MACH_H8300S:
7953 case E_H8_MACH_H8300SX:
7954 eh_addr_size = 4;
7955 break;
7957 break;
7959 case EM_M32C_OLD:
7960 case EM_M32C:
7961 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
7963 case EF_M32C_CPU_M16C:
7964 eh_addr_size = 2;
7965 break;
7967 break;
7970 #define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7971 do \
7973 uint64_t expected_entsize = is_32bit_elf ? size32 : size64; \
7974 if (section->sh_entsize != expected_entsize) \
7976 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
7977 i, section->sh_entsize); \
7978 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
7979 expected_entsize); \
7980 section->sh_entsize = expected_entsize; \
7983 while (0)
7985 #define CHECK_ENTSIZE(section, i, type) \
7986 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
7987 sizeof (Elf64_External_##type))
7989 for (i = 0, section = filedata->section_headers;
7990 i < filedata->file_header.e_shnum;
7991 i++, section++)
7993 const char *name = printable_section_name (filedata, section);
7995 /* Run some sanity checks on the headers and
7996 possibly fill in some file data as well. */
7997 switch (section->sh_type)
7999 case SHT_DYNSYM:
8000 if (filedata->dynamic_symbols != NULL)
8002 error (_("File contains multiple dynamic symbol tables\n"));
8003 continue;
8006 CHECK_ENTSIZE (section, i, Sym);
8007 filedata->dynamic_symbols
8008 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8009 filedata->dynamic_symtab_section = section;
8010 break;
8012 case SHT_STRTAB:
8013 if (streq (name, ".dynstr"))
8015 if (filedata->dynamic_strings != NULL)
8017 error (_("File contains multiple dynamic string tables\n"));
8018 continue;
8021 filedata->dynamic_strings
8022 = (char *) get_data (NULL, filedata, section->sh_offset,
8023 1, section->sh_size, _("dynamic strings"));
8024 filedata->dynamic_strings_length
8025 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8026 filedata->dynamic_strtab_section = section;
8028 break;
8030 case SHT_SYMTAB_SHNDX:
8032 elf_section_list * entry = xmalloc (sizeof * entry);
8034 entry->hdr = section;
8035 entry->next = filedata->symtab_shndx_list;
8036 filedata->symtab_shndx_list = entry;
8038 break;
8040 case SHT_SYMTAB:
8041 CHECK_ENTSIZE (section, i, Sym);
8042 break;
8044 case SHT_GROUP:
8045 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
8046 break;
8048 case SHT_REL:
8049 CHECK_ENTSIZE (section, i, Rel);
8050 if (do_checks && section->sh_size == 0)
8051 warn (_("Section '%s': zero-sized relocation section\n"), name);
8052 break;
8054 case SHT_RELA:
8055 CHECK_ENTSIZE (section, i, Rela);
8056 if (do_checks && section->sh_size == 0)
8057 warn (_("Section '%s': zero-sized relocation section\n"), name);
8058 break;
8060 case SHT_RELR:
8061 CHECK_ENTSIZE (section, i, Relr);
8062 break;
8064 case SHT_NOTE:
8065 case SHT_PROGBITS:
8066 /* Having a zero sized section is not illegal according to the
8067 ELF standard, but it might be an indication that something
8068 is wrong. So issue a warning if we are running in lint mode. */
8069 if (do_checks && section->sh_size == 0)
8070 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
8071 break;
8073 default:
8074 break;
8077 if ((do_debugging || do_debug_info || do_debug_abbrevs
8078 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
8079 || do_debug_aranges || do_debug_frames || do_debug_macinfo
8080 || do_debug_str || do_debug_str_offsets || do_debug_loc
8081 || do_debug_ranges
8082 || do_debug_addr || do_debug_cu_index || do_debug_links)
8083 && (startswith (name, ".debug_")
8084 || startswith (name, ".zdebug_")))
8086 if (name[1] == 'z')
8087 name += sizeof (".zdebug_") - 1;
8088 else
8089 name += sizeof (".debug_") - 1;
8091 if (do_debugging
8092 || (do_debug_info && startswith (name, "info"))
8093 || (do_debug_info && startswith (name, "types"))
8094 || (do_debug_abbrevs && startswith (name, "abbrev"))
8095 || (do_debug_lines && strcmp (name, "line") == 0)
8096 || (do_debug_lines && startswith (name, "line."))
8097 || (do_debug_pubnames && startswith (name, "pubnames"))
8098 || (do_debug_pubtypes && startswith (name, "pubtypes"))
8099 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
8100 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
8101 || (do_debug_aranges && startswith (name, "aranges"))
8102 || (do_debug_ranges && startswith (name, "ranges"))
8103 || (do_debug_ranges && startswith (name, "rnglists"))
8104 || (do_debug_frames && startswith (name, "frame"))
8105 || (do_debug_macinfo && startswith (name, "macinfo"))
8106 || (do_debug_macinfo && startswith (name, "macro"))
8107 || (do_debug_str && startswith (name, "str"))
8108 || (do_debug_links && startswith (name, "sup"))
8109 || (do_debug_str_offsets && startswith (name, "str_offsets"))
8110 || (do_debug_loc && startswith (name, "loc"))
8111 || (do_debug_loc && startswith (name, "loclists"))
8112 || (do_debug_addr && startswith (name, "addr"))
8113 || (do_debug_cu_index && startswith (name, "cu_index"))
8114 || (do_debug_cu_index && startswith (name, "tu_index"))
8116 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
8118 /* Linkonce section to be combined with .debug_info at link time. */
8119 else if ((do_debugging || do_debug_info)
8120 && startswith (name, ".gnu.linkonce.wi."))
8121 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
8122 else if (do_debug_frames && streq (name, ".eh_frame"))
8123 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
8124 else if (do_debug_frames && streq (name, ".eh_frame_hdr"))
8125 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
8126 else if (do_gdb_index && (streq (name, ".gdb_index")
8127 || streq (name, ".debug_names")))
8128 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
8129 /* Trace sections for Itanium VMS. */
8130 else if ((do_debugging || do_trace_info || do_trace_abbrevs
8131 || do_trace_aranges)
8132 && startswith (name, ".trace_"))
8134 name += sizeof (".trace_") - 1;
8136 if (do_debugging
8137 || (do_trace_info && streq (name, "info"))
8138 || (do_trace_abbrevs && streq (name, "abbrev"))
8139 || (do_trace_aranges && streq (name, "aranges"))
8141 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
8143 else if ((do_debugging || do_debug_links)
8144 && (startswith (name, ".gnu_debuglink")
8145 || startswith (name, ".gnu_debugaltlink")))
8146 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
8149 if (! do_sections)
8150 return true;
8152 if (filedata->is_separate && ! process_links)
8153 return true;
8155 if (filedata->is_separate)
8156 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
8157 else if (filedata->file_header.e_shnum > 1)
8158 printf (_("\nSection Headers:\n"));
8159 else
8160 printf (_("\nSection Header:\n"));
8162 if (is_32bit_elf)
8164 if (do_section_details)
8166 printf (_(" [Nr] Name\n"));
8167 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
8169 else
8170 printf
8171 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
8173 else if (do_wide)
8175 if (do_section_details)
8177 printf (_(" [Nr] Name\n"));
8178 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
8180 else
8181 printf
8182 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
8184 else
8186 if (do_section_details)
8188 printf (_(" [Nr] Name\n"));
8189 printf (_(" Type Address Offset Link\n"));
8190 printf (_(" Size EntSize Info Align\n"));
8192 else
8194 printf (_(" [Nr] Name Type Address Offset\n"));
8195 printf (_(" Size EntSize Flags Link Info Align\n"));
8199 if (do_section_details)
8200 printf (_(" Flags\n"));
8202 for (i = 0, section = filedata->section_headers;
8203 i < filedata->file_header.e_shnum;
8204 i++, section++)
8206 /* Run some sanity checks on the section header. */
8208 /* Check the sh_link field. */
8209 switch (section->sh_type)
8211 case SHT_REL:
8212 case SHT_RELR:
8213 case SHT_RELA:
8214 if (section->sh_link == 0
8215 && (filedata->file_header.e_type == ET_EXEC
8216 || filedata->file_header.e_type == ET_DYN))
8217 /* A dynamic relocation section where all entries use a
8218 zero symbol index need not specify a symtab section. */
8219 break;
8220 /* Fall through. */
8221 case SHT_SYMTAB_SHNDX:
8222 case SHT_GROUP:
8223 case SHT_HASH:
8224 case SHT_GNU_HASH:
8225 case SHT_GNU_versym:
8226 if (section->sh_link == 0
8227 || section->sh_link >= filedata->file_header.e_shnum
8228 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
8229 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
8230 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
8231 i, section->sh_link);
8232 break;
8234 case SHT_DYNAMIC:
8235 case SHT_SYMTAB:
8236 case SHT_DYNSYM:
8237 case SHT_GNU_verneed:
8238 case SHT_GNU_verdef:
8239 case SHT_GNU_LIBLIST:
8240 if (section->sh_link == 0
8241 || section->sh_link >= filedata->file_header.e_shnum
8242 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
8243 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
8244 i, section->sh_link);
8245 break;
8247 case SHT_INIT_ARRAY:
8248 case SHT_FINI_ARRAY:
8249 case SHT_PREINIT_ARRAY:
8250 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
8251 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
8252 i, section->sh_link);
8253 break;
8255 default:
8256 /* FIXME: Add support for target specific section types. */
8257 #if 0 /* Currently we do not check other section types as there are too
8258 many special cases. Stab sections for example have a type
8259 of SHT_PROGBITS but an sh_link field that links to the .stabstr
8260 section. */
8261 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
8262 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
8263 i, section->sh_link);
8264 #endif
8265 break;
8268 /* Check the sh_info field. */
8269 switch (section->sh_type)
8271 case SHT_REL:
8272 case SHT_RELA:
8273 if (section->sh_info == 0
8274 && (filedata->file_header.e_type == ET_EXEC
8275 || filedata->file_header.e_type == ET_DYN))
8276 /* Dynamic relocations apply to segments, so they do not
8277 need to specify the section they relocate. */
8278 break;
8279 if (section->sh_info == 0
8280 || section->sh_info >= filedata->file_header.e_shnum
8281 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
8282 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
8283 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
8284 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
8285 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
8286 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
8287 /* FIXME: Are other section types valid ? */
8288 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
8289 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
8290 i, section->sh_info);
8291 break;
8293 case SHT_DYNAMIC:
8294 case SHT_HASH:
8295 case SHT_SYMTAB_SHNDX:
8296 case SHT_INIT_ARRAY:
8297 case SHT_FINI_ARRAY:
8298 case SHT_PREINIT_ARRAY:
8299 if (section->sh_info != 0)
8300 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
8301 i, section->sh_info);
8302 break;
8304 case SHT_GROUP:
8305 case SHT_SYMTAB:
8306 case SHT_DYNSYM:
8307 /* A symbol index - we assume that it is valid. */
8308 break;
8310 default:
8311 /* FIXME: Add support for target specific section types. */
8312 if (section->sh_type == SHT_NOBITS)
8313 /* NOBITS section headers with non-zero sh_info fields can be
8314 created when a binary is stripped of everything but its debug
8315 information. The stripped sections have their headers
8316 preserved but their types set to SHT_NOBITS. So do not check
8317 this type of section. */
8319 else if (section->sh_flags & SHF_INFO_LINK)
8321 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
8322 warn (_("[%2u]: Expected link to another section in info field"), i);
8324 else if (section->sh_type < SHT_LOOS
8325 && (section->sh_flags & SHF_GNU_MBIND) == 0
8326 && section->sh_info != 0)
8327 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
8328 i, section->sh_info);
8329 break;
8332 /* Check the sh_size field. */
8333 if (section->sh_size > filedata->file_size
8334 && section->sh_type != SHT_NOBITS
8335 && section->sh_type != SHT_NULL
8336 && section->sh_type < SHT_LOOS)
8337 warn (_("Size of section %u is larger than the entire file!\n"), i);
8339 printf (" [%2u] ", i);
8340 if (do_section_details)
8341 printf ("%s\n ", printable_section_name (filedata, section));
8342 else
8343 print_symbol_name (-17, printable_section_name (filedata, section));
8345 printf (do_wide ? " %-15s " : " %-15.15s ",
8346 get_section_type_name (filedata, section->sh_type));
8348 if (is_32bit_elf)
8350 const char * link_too_big = NULL;
8352 print_vma (section->sh_addr, LONG_HEX);
8354 printf ( " %6.6lx %6.6lx %2.2lx",
8355 (unsigned long) section->sh_offset,
8356 (unsigned long) section->sh_size,
8357 (unsigned long) section->sh_entsize);
8359 if (do_section_details)
8360 fputs (" ", stdout);
8361 else
8362 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
8364 if (section->sh_link >= filedata->file_header.e_shnum)
8366 link_too_big = "";
8367 /* The sh_link value is out of range. Normally this indicates
8368 an error but it can have special values in Solaris binaries. */
8369 switch (filedata->file_header.e_machine)
8371 case EM_386:
8372 case EM_IAMCU:
8373 case EM_X86_64:
8374 case EM_L1OM:
8375 case EM_K1OM:
8376 case EM_OLD_SPARCV9:
8377 case EM_SPARC32PLUS:
8378 case EM_SPARCV9:
8379 case EM_SPARC:
8380 if (section->sh_link == (SHN_BEFORE & 0xffff))
8381 link_too_big = "BEFORE";
8382 else if (section->sh_link == (SHN_AFTER & 0xffff))
8383 link_too_big = "AFTER";
8384 break;
8385 default:
8386 break;
8390 if (do_section_details)
8392 if (link_too_big != NULL && * link_too_big)
8393 printf ("<%s> ", link_too_big);
8394 else
8395 printf ("%2u ", section->sh_link);
8396 printf ("%3u %2lu\n", section->sh_info,
8397 (unsigned long) section->sh_addralign);
8399 else
8400 printf ("%2u %3u %2lu\n",
8401 section->sh_link,
8402 section->sh_info,
8403 (unsigned long) section->sh_addralign);
8405 if (link_too_big && ! * link_too_big)
8406 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
8407 i, section->sh_link);
8409 else if (do_wide)
8411 print_vma (section->sh_addr, LONG_HEX);
8413 if ((long) section->sh_offset == section->sh_offset)
8414 printf (" %6.6lx", (unsigned long) section->sh_offset);
8415 else
8417 putchar (' ');
8418 print_vma (section->sh_offset, LONG_HEX);
8421 if ((unsigned long) section->sh_size == section->sh_size)
8422 printf (" %6.6lx", (unsigned long) section->sh_size);
8423 else
8425 putchar (' ');
8426 print_vma (section->sh_size, LONG_HEX);
8429 if ((unsigned long) section->sh_entsize == section->sh_entsize)
8430 printf (" %2.2lx", (unsigned long) section->sh_entsize);
8431 else
8433 putchar (' ');
8434 print_vma (section->sh_entsize, LONG_HEX);
8437 if (do_section_details)
8438 fputs (" ", stdout);
8439 else
8440 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
8442 printf ("%2u %3u ", section->sh_link, section->sh_info);
8444 if ((unsigned long) section->sh_addralign == section->sh_addralign)
8445 printf ("%2lu\n", (unsigned long) section->sh_addralign);
8446 else
8448 print_vma (section->sh_addralign, DEC);
8449 putchar ('\n');
8452 else if (do_section_details)
8454 putchar (' ');
8455 print_vma (section->sh_addr, LONG_HEX);
8456 if ((long) section->sh_offset == section->sh_offset)
8457 printf (" %16.16lx", (unsigned long) section->sh_offset);
8458 else
8460 printf (" ");
8461 print_vma (section->sh_offset, LONG_HEX);
8463 printf (" %u\n ", section->sh_link);
8464 print_vma (section->sh_size, LONG_HEX);
8465 putchar (' ');
8466 print_vma (section->sh_entsize, LONG_HEX);
8468 printf (" %-16u %lu\n",
8469 section->sh_info,
8470 (unsigned long) section->sh_addralign);
8472 else
8474 putchar (' ');
8475 print_vma (section->sh_addr, LONG_HEX);
8476 if ((long) section->sh_offset == section->sh_offset)
8477 printf (" %8.8lx", (unsigned long) section->sh_offset);
8478 else
8480 printf (" ");
8481 print_vma (section->sh_offset, LONG_HEX);
8483 printf ("\n ");
8484 print_vma (section->sh_size, LONG_HEX);
8485 printf (" ");
8486 print_vma (section->sh_entsize, LONG_HEX);
8488 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
8490 printf (" %2u %3u %lu\n",
8491 section->sh_link,
8492 section->sh_info,
8493 (unsigned long) section->sh_addralign);
8496 if (do_section_details)
8498 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
8499 if ((section->sh_flags & SHF_COMPRESSED) != 0)
8501 /* Minimum section size is 12 bytes for 32-bit compression
8502 header + 12 bytes for compressed data header. */
8503 unsigned char buf[24];
8505 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
8506 if (get_data (&buf, filedata, section->sh_offset, 1,
8507 sizeof (buf), _("compression header")))
8509 Elf_Internal_Chdr chdr;
8511 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
8512 printf (_(" [<corrupt>]\n"));
8513 else
8515 if (chdr.ch_type == ch_compress_zlib)
8516 printf (" ZLIB, ");
8517 else if (chdr.ch_type == ch_compress_zstd)
8518 printf (" ZSTD, ");
8519 else
8520 printf (_(" [<unknown>: 0x%x], "),
8521 chdr.ch_type);
8522 print_vma (chdr.ch_size, LONG_HEX);
8523 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
8530 if (!do_section_details)
8532 /* The ordering of the letters shown here matches the ordering of the
8533 corresponding SHF_xxx values, and hence the order in which these
8534 letters will be displayed to the user. */
8535 printf (_("Key to Flags:\n\
8536 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
8537 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
8538 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
8539 switch (filedata->file_header.e_ident[EI_OSABI])
8541 case ELFOSABI_GNU:
8542 case ELFOSABI_FREEBSD:
8543 printf (_("R (retain), "));
8544 /* Fall through */
8545 case ELFOSABI_NONE:
8546 printf (_("D (mbind), "));
8547 break;
8548 default:
8549 break;
8551 if (filedata->file_header.e_machine == EM_X86_64
8552 || filedata->file_header.e_machine == EM_L1OM
8553 || filedata->file_header.e_machine == EM_K1OM)
8554 printf (_("l (large), "));
8555 else if (filedata->file_header.e_machine == EM_ARM)
8556 printf (_("y (purecode), "));
8557 else if (filedata->file_header.e_machine == EM_PPC)
8558 printf (_("v (VLE), "));
8559 printf ("p (processor specific)\n");
8562 return true;
8565 static bool
8566 get_symtab (Filedata * filedata,
8567 Elf_Internal_Shdr * symsec,
8568 Elf_Internal_Sym ** symtab,
8569 uint64_t * nsyms,
8570 char ** strtab,
8571 uint64_t * strtablen)
8573 *strtab = NULL;
8574 *strtablen = 0;
8575 *symtab = get_elf_symbols (filedata, symsec, nsyms);
8577 if (*symtab == NULL)
8578 return false;
8580 if (symsec->sh_link != 0)
8582 Elf_Internal_Shdr *strsec;
8584 if (symsec->sh_link >= filedata->file_header.e_shnum)
8586 error (_("Bad sh_link in symbol table section\n"));
8587 free (*symtab);
8588 *symtab = NULL;
8589 *nsyms = 0;
8590 return false;
8593 strsec = filedata->section_headers + symsec->sh_link;
8595 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
8596 1, strsec->sh_size, _("string table"));
8597 if (*strtab == NULL)
8599 free (*symtab);
8600 *symtab = NULL;
8601 *nsyms = 0;
8602 return false;
8604 *strtablen = strsec->sh_size;
8606 return true;
8609 static const char *
8610 get_group_flags (unsigned int flags)
8612 static char buff[128];
8614 if (flags == 0)
8615 return "";
8616 else if (flags == GRP_COMDAT)
8617 return "COMDAT ";
8619 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
8620 flags,
8621 flags & GRP_MASKOS ? _("<OS specific>") : "",
8622 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
8623 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
8624 ? _("<unknown>") : ""));
8626 return buff;
8629 static bool
8630 process_section_groups (Filedata * filedata)
8632 Elf_Internal_Shdr * section;
8633 unsigned int i;
8634 struct group * group;
8635 Elf_Internal_Shdr * symtab_sec;
8636 Elf_Internal_Shdr * strtab_sec;
8637 Elf_Internal_Sym * symtab;
8638 uint64_t num_syms;
8639 char * strtab;
8640 size_t strtab_size;
8642 /* Don't process section groups unless needed. */
8643 if (!do_unwind && !do_section_groups)
8644 return true;
8646 if (filedata->file_header.e_shnum == 0)
8648 if (do_section_groups)
8650 if (filedata->is_separate)
8651 printf (_("\nThere are no sections group in linked file '%s'.\n"),
8652 filedata->file_name);
8653 else
8654 printf (_("\nThere are no section groups in this file.\n"));
8656 return true;
8659 if (filedata->section_headers == NULL)
8661 error (_("Section headers are not available!\n"));
8662 /* PR 13622: This can happen with a corrupt ELF header. */
8663 return false;
8666 filedata->section_headers_groups
8667 = (struct group **) calloc (filedata->file_header.e_shnum,
8668 sizeof (struct group *));
8670 if (filedata->section_headers_groups == NULL)
8672 error (_("Out of memory reading %u section group headers\n"),
8673 filedata->file_header.e_shnum);
8674 return false;
8677 /* Scan the sections for the group section. */
8678 filedata->group_count = 0;
8679 for (i = 0, section = filedata->section_headers;
8680 i < filedata->file_header.e_shnum;
8681 i++, section++)
8682 if (section->sh_type == SHT_GROUP)
8683 filedata->group_count++;
8685 if (filedata->group_count == 0)
8687 if (do_section_groups)
8689 if (filedata->is_separate)
8690 printf (_("\nThere are no section groups in linked file '%s'.\n"),
8691 filedata->file_name);
8692 else
8693 printf (_("\nThere are no section groups in this file.\n"));
8696 return true;
8699 filedata->section_groups = (struct group *) calloc (filedata->group_count,
8700 sizeof (struct group));
8702 if (filedata->section_groups == NULL)
8704 error (_("Out of memory reading %zu groups\n"), filedata->group_count);
8705 return false;
8708 symtab_sec = NULL;
8709 strtab_sec = NULL;
8710 symtab = NULL;
8711 num_syms = 0;
8712 strtab = NULL;
8713 strtab_size = 0;
8715 if (filedata->is_separate)
8716 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
8718 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
8719 i < filedata->file_header.e_shnum;
8720 i++, section++)
8722 if (section->sh_type == SHT_GROUP)
8724 const char * name = printable_section_name (filedata, section);
8725 const char * group_name;
8726 unsigned char * start;
8727 unsigned char * indices;
8728 unsigned int entry, j, size;
8729 Elf_Internal_Shdr * sec;
8730 Elf_Internal_Sym * sym;
8732 /* Get the symbol table. */
8733 if (section->sh_link >= filedata->file_header.e_shnum
8734 || ((sec = filedata->section_headers + section->sh_link)->sh_type
8735 != SHT_SYMTAB))
8737 error (_("Bad sh_link in group section `%s'\n"), name);
8738 continue;
8741 if (symtab_sec != sec)
8743 symtab_sec = sec;
8744 free (symtab);
8745 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
8748 if (symtab == NULL)
8750 error (_("Corrupt header in group section `%s'\n"), name);
8751 continue;
8754 if (section->sh_info >= num_syms)
8756 error (_("Bad sh_info in group section `%s'\n"), name);
8757 continue;
8760 sym = symtab + section->sh_info;
8762 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
8764 if (sym->st_shndx == 0
8765 || sym->st_shndx >= filedata->file_header.e_shnum)
8767 error (_("Bad sh_info in group section `%s'\n"), name);
8768 continue;
8771 group_name = printable_section_name (filedata,
8772 filedata->section_headers
8773 + sym->st_shndx);
8774 strtab_sec = NULL;
8775 free (strtab);
8776 strtab = NULL;
8777 strtab_size = 0;
8779 else
8781 /* Get the string table. */
8782 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
8784 strtab_sec = NULL;
8785 free (strtab);
8786 strtab = NULL;
8787 strtab_size = 0;
8789 else if (strtab_sec
8790 != (sec = filedata->section_headers + symtab_sec->sh_link))
8792 strtab_sec = sec;
8793 free (strtab);
8795 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
8796 1, strtab_sec->sh_size,
8797 _("string table"));
8798 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
8800 group_name = sym->st_name < strtab_size
8801 ? strtab + sym->st_name : _("<corrupt>");
8804 /* PR 17531: file: loop. */
8805 if (section->sh_entsize > section->sh_size)
8807 error (_("Section %s has sh_entsize (%#" PRIx64 ")"
8808 " which is larger than its size (%#" PRIx64 ")\n"),
8809 printable_section_name (filedata, section),
8810 section->sh_entsize,
8811 section->sh_size);
8812 continue;
8815 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
8816 1, section->sh_size,
8817 _("section data"));
8818 if (start == NULL)
8819 continue;
8821 indices = start;
8822 size = (section->sh_size / section->sh_entsize) - 1;
8823 entry = byte_get (indices, 4);
8824 indices += 4;
8826 if (do_section_groups)
8828 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
8829 get_group_flags (entry), i, name, group_name, size);
8831 printf (_(" [Index] Name\n"));
8834 group->group_index = i;
8836 for (j = 0; j < size; j++)
8838 struct group_list * g;
8840 entry = byte_get (indices, 4);
8841 indices += 4;
8843 if (entry >= filedata->file_header.e_shnum)
8845 static unsigned num_group_errors = 0;
8847 if (num_group_errors ++ < 10)
8849 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
8850 entry, i, filedata->file_header.e_shnum - 1);
8851 if (num_group_errors == 10)
8852 warn (_("Further error messages about overlarge group section indices suppressed\n"));
8854 continue;
8857 if (filedata->section_headers_groups [entry] != NULL)
8859 if (entry)
8861 static unsigned num_errs = 0;
8863 if (num_errs ++ < 10)
8865 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
8866 entry, i,
8867 filedata->section_headers_groups [entry]->group_index);
8868 if (num_errs == 10)
8869 warn (_("Further error messages about already contained group sections suppressed\n"));
8871 continue;
8873 else
8875 /* Intel C/C++ compiler may put section 0 in a
8876 section group. We just warn it the first time
8877 and ignore it afterwards. */
8878 static bool warned = false;
8879 if (!warned)
8881 error (_("section 0 in group section [%5u]\n"),
8882 filedata->section_headers_groups [entry]->group_index);
8883 warned = true;
8888 filedata->section_headers_groups [entry] = group;
8890 if (do_section_groups)
8892 sec = filedata->section_headers + entry;
8893 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
8896 g = (struct group_list *) xmalloc (sizeof (struct group_list));
8897 g->section_index = entry;
8898 g->next = group->root;
8899 group->root = g;
8902 free (start);
8904 group++;
8908 free (symtab);
8909 free (strtab);
8910 return true;
8913 /* Data used to display dynamic fixups. */
8915 struct ia64_vms_dynfixup
8917 uint64_t needed_ident; /* Library ident number. */
8918 uint64_t needed; /* Index in the dstrtab of the library name. */
8919 uint64_t fixup_needed; /* Index of the library. */
8920 uint64_t fixup_rela_cnt; /* Number of fixups. */
8921 uint64_t fixup_rela_off; /* Fixups offset in the dynamic segment. */
8924 /* Data used to display dynamic relocations. */
8926 struct ia64_vms_dynimgrela
8928 uint64_t img_rela_cnt; /* Number of relocations. */
8929 uint64_t img_rela_off; /* Reloc offset in the dynamic segment. */
8932 /* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
8933 library). */
8935 static bool
8936 dump_ia64_vms_dynamic_fixups (Filedata * filedata,
8937 struct ia64_vms_dynfixup * fixup,
8938 const char * strtab,
8939 unsigned int strtab_sz)
8941 Elf64_External_VMS_IMAGE_FIXUP * imfs;
8942 size_t i;
8943 const char * lib_name;
8945 imfs = get_data (NULL, filedata,
8946 filedata->dynamic_addr + fixup->fixup_rela_off,
8947 sizeof (*imfs), fixup->fixup_rela_cnt,
8948 _("dynamic section image fixups"));
8949 if (!imfs)
8950 return false;
8952 if (fixup->needed < strtab_sz)
8953 lib_name = strtab + fixup->needed;
8954 else
8956 warn (_("corrupt library name index of %#" PRIx64
8957 " found in dynamic entry"), fixup->needed);
8958 lib_name = "???";
8961 printf (_("\nImage fixups for needed library #%" PRId64
8962 ": %s - ident: %" PRIx64 "\n"),
8963 fixup->fixup_needed, lib_name, fixup->needed_ident);
8964 printf
8965 (_("Seg Offset Type SymVec DataType\n"));
8967 for (i = 0; i < (size_t) fixup->fixup_rela_cnt; i++)
8969 unsigned int type;
8970 const char *rtype;
8972 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
8973 printf ("%016" PRIx64 " ", BYTE_GET (imfs [i].fixup_offset));
8974 type = BYTE_GET (imfs [i].type);
8975 rtype = elf_ia64_reloc_type (type);
8976 if (rtype == NULL)
8977 printf ("0x%08x ", type);
8978 else
8979 printf ("%-32s ", rtype);
8980 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8981 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8984 free (imfs);
8985 return true;
8988 /* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8990 static bool
8991 dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
8993 Elf64_External_VMS_IMAGE_RELA *imrs;
8994 size_t i;
8996 imrs = get_data (NULL, filedata,
8997 filedata->dynamic_addr + imgrela->img_rela_off,
8998 sizeof (*imrs), imgrela->img_rela_cnt,
8999 _("dynamic section image relocations"));
9000 if (!imrs)
9001 return false;
9003 printf (_("\nImage relocs\n"));
9004 printf
9005 (_("Seg Offset Type Addend Seg Sym Off\n"));
9007 for (i = 0; i < (size_t) imgrela->img_rela_cnt; i++)
9009 unsigned int type;
9010 const char *rtype;
9012 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
9013 printf ("%08" PRIx64 " ", BYTE_GET (imrs [i].rela_offset));
9014 type = BYTE_GET (imrs [i].type);
9015 rtype = elf_ia64_reloc_type (type);
9016 if (rtype == NULL)
9017 printf ("0x%08x ", type);
9018 else
9019 printf ("%-31s ", rtype);
9020 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
9021 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
9022 printf ("%08" PRIx64 "\n", BYTE_GET (imrs [i].sym_offset));
9025 free (imrs);
9026 return true;
9029 /* Display IA-64 OpenVMS dynamic relocations and fixups. */
9031 static bool
9032 process_ia64_vms_dynamic_relocs (Filedata * filedata)
9034 struct ia64_vms_dynfixup fixup;
9035 struct ia64_vms_dynimgrela imgrela;
9036 Elf_Internal_Dyn *entry;
9037 uint64_t strtab_off = 0;
9038 uint64_t strtab_sz = 0;
9039 char *strtab = NULL;
9040 bool res = true;
9042 memset (&fixup, 0, sizeof (fixup));
9043 memset (&imgrela, 0, sizeof (imgrela));
9045 /* Note: the order of the entries is specified by the OpenVMS specs. */
9046 for (entry = filedata->dynamic_section;
9047 entry < filedata->dynamic_section + filedata->dynamic_nent;
9048 entry++)
9050 switch (entry->d_tag)
9052 case DT_IA_64_VMS_STRTAB_OFFSET:
9053 strtab_off = entry->d_un.d_val;
9054 break;
9055 case DT_STRSZ:
9056 strtab_sz = entry->d_un.d_val;
9057 if (strtab == NULL)
9058 strtab = get_data (NULL, filedata,
9059 filedata->dynamic_addr + strtab_off,
9060 1, strtab_sz, _("dynamic string section"));
9061 if (strtab == NULL)
9062 strtab_sz = 0;
9063 break;
9065 case DT_IA_64_VMS_NEEDED_IDENT:
9066 fixup.needed_ident = entry->d_un.d_val;
9067 break;
9068 case DT_NEEDED:
9069 fixup.needed = entry->d_un.d_val;
9070 break;
9071 case DT_IA_64_VMS_FIXUP_NEEDED:
9072 fixup.fixup_needed = entry->d_un.d_val;
9073 break;
9074 case DT_IA_64_VMS_FIXUP_RELA_CNT:
9075 fixup.fixup_rela_cnt = entry->d_un.d_val;
9076 break;
9077 case DT_IA_64_VMS_FIXUP_RELA_OFF:
9078 fixup.fixup_rela_off = entry->d_un.d_val;
9079 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
9080 res = false;
9081 break;
9082 case DT_IA_64_VMS_IMG_RELA_CNT:
9083 imgrela.img_rela_cnt = entry->d_un.d_val;
9084 break;
9085 case DT_IA_64_VMS_IMG_RELA_OFF:
9086 imgrela.img_rela_off = entry->d_un.d_val;
9087 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
9088 res = false;
9089 break;
9091 default:
9092 break;
9096 free (strtab);
9098 return res;
9101 static struct
9103 const char * name;
9104 int reloc;
9105 int size;
9106 relocation_type rel_type;
9108 dynamic_relocations [] =
9110 { "REL", DT_REL, DT_RELSZ, reltype_rel },
9111 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
9112 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
9113 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
9116 static relocation_type
9117 rel_type_from_sh_type (unsigned int sh_type)
9119 switch (sh_type)
9121 case SHT_RELA: return reltype_rela;
9122 case SHT_REL: return reltype_rel;
9123 case SHT_RELR: return reltype_relr;
9124 default: return reltype_unknown;
9128 static bool
9129 display_relocations (Elf_Internal_Shdr * section,
9130 Filedata * filedata)
9132 relocation_type rel_type = rel_type_from_sh_type (section->sh_type);
9134 if (rel_type == reltype_unknown)
9135 return false;
9137 uint64_t rel_size = section->sh_size;
9139 if (rel_size == 0)
9140 return false;
9142 if (filedata->is_separate)
9143 printf (_("\nIn linked file '%s' relocation section "),
9144 filedata->file_name);
9145 else
9146 printf (_("\nRelocation section "));
9148 if (filedata->string_table == NULL)
9149 printf ("%d", section->sh_name);
9150 else
9151 printf ("'%s'", printable_section_name (filedata, section));
9153 uint64_t num_rela = rel_size / section->sh_entsize;
9154 uint64_t rel_offset = section->sh_offset;
9156 if (rel_type == reltype_relr)
9158 /* Just stating the 'number of entries' in a RELR section can be
9159 misleading, since this is not the number of locations relocated, but
9160 the number of words in the compressed RELR format. So also provide
9161 the number of locations affected. */
9162 if (num_rela == 1)
9163 /* This is unlikely, but possible. */
9164 printf (_(" at offset %#" PRIx64
9165 " contains 1 entry which relocates 1 location:\n"),
9166 rel_offset);
9167 else
9168 printf (_(" at offset %#" PRIx64 " contains %" PRIu64
9169 " entries which relocate %" PRIu64 " locations:\n"),
9170 rel_offset, num_rela, count_relr_relocations (filedata, section));
9172 else
9174 printf (ngettext (" at offset %#" PRIx64
9175 " contains %" PRIu64 " entry:\n",
9176 " at offset %#" PRIx64
9177 " contains %" PRIu64 " entries:\n",
9178 num_rela),
9179 rel_offset, num_rela);
9182 Elf_Internal_Shdr * symsec;
9183 Elf_Internal_Sym * symtab = NULL;
9184 uint64_t nsyms = 0;
9185 uint64_t strtablen = 0;
9186 char * strtab = NULL;
9188 if (section->sh_link == 0
9189 || section->sh_link >= filedata->file_header.e_shnum)
9191 /* Symbol data not available.
9192 This can happen, especially with RELR relocs.
9193 See if there is a .symtab section present.
9194 If so then use it. */
9195 symsec = find_section_by_name (filedata, ".symtab");
9197 else
9199 symsec = filedata->section_headers + section->sh_link;
9201 if (symsec->sh_type != SHT_SYMTAB
9202 && symsec->sh_type != SHT_DYNSYM)
9203 return false;
9206 if (symsec != NULL
9207 && !get_symtab (filedata, symsec, &symtab, &nsyms, &strtab, &strtablen))
9208 return false;
9210 bool res;
9212 if (rel_type == reltype_relr)
9213 res = dump_relr_relocations (filedata, section, symtab, nsyms, strtab, strtablen);
9214 else
9215 res = dump_relocations (filedata, rel_offset, rel_size,
9216 symtab, nsyms, strtab, strtablen,
9217 rel_type,
9218 symsec == NULL ? false : symsec->sh_type == SHT_DYNSYM);
9219 free (strtab);
9220 free (symtab);
9222 return res;
9225 /* Process the reloc section. */
9227 static bool
9228 process_relocs (Filedata * filedata)
9230 uint64_t rel_size;
9231 uint64_t rel_offset;
9233 if (!do_reloc)
9234 return true;
9236 if (do_using_dynamic)
9238 relocation_type rel_type;
9239 const char * name;
9240 bool has_dynamic_reloc;
9241 unsigned int i;
9243 has_dynamic_reloc = false;
9245 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
9247 rel_type = dynamic_relocations [i].rel_type;
9248 name = dynamic_relocations [i].name;
9249 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
9250 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
9252 if (rel_size)
9253 has_dynamic_reloc = true;
9255 if (rel_type == reltype_unknown)
9257 if (dynamic_relocations [i].reloc == DT_JMPREL)
9258 switch (filedata->dynamic_info[DT_PLTREL])
9260 case DT_REL:
9261 rel_type = reltype_rel;
9262 break;
9263 case DT_RELA:
9264 rel_type = reltype_rela;
9265 break;
9269 if (rel_size)
9271 if (filedata->is_separate)
9272 printf
9273 (_("\nIn linked file '%s' section '%s' at offset %#" PRIx64
9274 " contains %" PRId64 " bytes:\n"),
9275 filedata->file_name, name, rel_offset, rel_size);
9276 else
9277 printf
9278 (_("\n'%s' relocation section at offset %#" PRIx64
9279 " contains %" PRId64 " bytes:\n"),
9280 name, rel_offset, rel_size);
9282 dump_relocations (filedata,
9283 offset_from_vma (filedata, rel_offset, rel_size),
9284 rel_size,
9285 filedata->dynamic_symbols,
9286 filedata->num_dynamic_syms,
9287 filedata->dynamic_strings,
9288 filedata->dynamic_strings_length,
9289 rel_type, true /* is_dynamic */);
9293 if (is_ia64_vms (filedata))
9294 if (process_ia64_vms_dynamic_relocs (filedata))
9295 has_dynamic_reloc = true;
9297 if (! has_dynamic_reloc)
9299 if (filedata->is_separate)
9300 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
9301 filedata->file_name);
9302 else
9303 printf (_("\nThere are no dynamic relocations in this file.\n"));
9306 else
9308 Elf_Internal_Shdr * section;
9309 size_t i;
9310 bool found = false;
9312 for (i = 0, section = filedata->section_headers;
9313 i < filedata->file_header.e_shnum;
9314 i++, section++)
9316 if (display_relocations (section, filedata))
9317 found = true;
9320 if (! found)
9322 /* Users sometimes forget the -D option, so try to be helpful. */
9323 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
9325 if (filedata->dynamic_info[dynamic_relocations [i].size])
9327 if (filedata->is_separate)
9328 printf (_("\nThere are no static relocations in linked file '%s'."),
9329 filedata->file_name);
9330 else
9331 printf (_("\nThere are no static relocations in this file."));
9332 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
9334 break;
9337 if (i == ARRAY_SIZE (dynamic_relocations))
9339 if (filedata->is_separate)
9340 printf (_("\nThere are no relocations in linked file '%s'.\n"),
9341 filedata->file_name);
9342 else
9343 printf (_("\nThere are no relocations in this file.\n"));
9348 return true;
9351 /* An absolute address consists of a section and an offset. If the
9352 section is NULL, the offset itself is the address, otherwise, the
9353 address equals to LOAD_ADDRESS(section) + offset. */
9355 struct absaddr
9357 unsigned short section;
9358 uint64_t offset;
9361 /* Find the nearest symbol at or below ADDR. Returns the symbol
9362 name, if found, and the offset from the symbol to ADDR. */
9364 static void
9365 find_symbol_for_address (Filedata *filedata,
9366 Elf_Internal_Sym *symtab,
9367 uint64_t nsyms,
9368 const char *strtab,
9369 uint64_t strtab_size,
9370 struct absaddr addr,
9371 const char **symname,
9372 uint64_t *offset)
9374 uint64_t dist = 0x100000;
9375 Elf_Internal_Sym * sym;
9376 Elf_Internal_Sym * beg;
9377 Elf_Internal_Sym * end;
9378 Elf_Internal_Sym * best = NULL;
9380 REMOVE_ARCH_BITS (addr.offset);
9381 beg = symtab;
9382 end = symtab + nsyms;
9384 while (beg < end)
9386 uint64_t value;
9388 sym = beg + (end - beg) / 2;
9390 value = sym->st_value;
9391 REMOVE_ARCH_BITS (value);
9393 if (sym->st_name != 0
9394 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
9395 && addr.offset >= value
9396 && addr.offset - value < dist)
9398 best = sym;
9399 dist = addr.offset - value;
9400 if (!dist)
9401 break;
9404 if (addr.offset < value)
9405 end = sym;
9406 else
9407 beg = sym + 1;
9410 if (best)
9412 *symname = (best->st_name >= strtab_size
9413 ? _("<corrupt>") : strtab + best->st_name);
9414 *offset = dist;
9415 return;
9418 *symname = NULL;
9419 *offset = addr.offset;
9422 /* Process the unwind section. */
9424 #include "unwind-ia64.h"
9426 struct ia64_unw_table_entry
9428 struct absaddr start;
9429 struct absaddr end;
9430 struct absaddr info;
9433 struct ia64_unw_aux_info
9435 struct ia64_unw_table_entry * table; /* Unwind table. */
9436 uint64_t table_len; /* Length of unwind table. */
9437 unsigned char * info; /* Unwind info. */
9438 uint64_t info_size; /* Size of unwind info. */
9439 uint64_t info_addr; /* Starting address of unwind info. */
9440 uint64_t seg_base; /* Starting address of segment. */
9441 Elf_Internal_Sym * symtab; /* The symbol table. */
9442 uint64_t nsyms; /* Number of symbols. */
9443 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9444 uint64_t nfuns; /* Number of entries in funtab. */
9445 char * strtab; /* The string table. */
9446 uint64_t strtab_size; /* Size of string table. */
9449 static bool
9450 dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
9452 struct ia64_unw_table_entry * tp;
9453 size_t j, nfuns;
9454 int in_body;
9455 bool res = true;
9457 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9458 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9459 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9460 aux->funtab[nfuns++] = aux->symtab[j];
9461 aux->nfuns = nfuns;
9462 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9464 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9466 uint64_t stamp;
9467 uint64_t offset;
9468 const unsigned char * dp;
9469 const unsigned char * head;
9470 const unsigned char * end;
9471 const char * procname;
9473 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
9474 aux->strtab_size, tp->start, &procname, &offset);
9476 fputs ("\n<", stdout);
9478 if (procname)
9480 fputs (procname, stdout);
9482 if (offset)
9483 printf ("+%" PRIx64, offset);
9486 fputs (">: [", stdout);
9487 print_vma (tp->start.offset, PREFIX_HEX);
9488 fputc ('-', stdout);
9489 print_vma (tp->end.offset, PREFIX_HEX);
9490 printf ("], info at +0x%" PRIx64 "\n",
9491 tp->info.offset - aux->seg_base);
9493 /* PR 17531: file: 86232b32. */
9494 if (aux->info == NULL)
9495 continue;
9497 offset = tp->info.offset;
9498 if (tp->info.section)
9500 if (tp->info.section >= filedata->file_header.e_shnum)
9502 warn (_("Invalid section %u in table entry %td\n"),
9503 tp->info.section, tp - aux->table);
9504 res = false;
9505 continue;
9507 offset += filedata->section_headers[tp->info.section].sh_addr;
9509 offset -= aux->info_addr;
9510 /* PR 17531: file: 0997b4d1. */
9511 if (offset >= aux->info_size
9512 || aux->info_size - offset < 8)
9514 warn (_("Invalid offset %" PRIx64 " in table entry %td\n"),
9515 tp->info.offset, tp - aux->table);
9516 res = false;
9517 continue;
9520 head = aux->info + offset;
9521 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
9523 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
9524 (unsigned) UNW_VER (stamp),
9525 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
9526 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
9527 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
9528 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
9530 if (UNW_VER (stamp) != 1)
9532 printf (_("\tUnknown version.\n"));
9533 continue;
9536 in_body = 0;
9537 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
9538 /* PR 17531: file: 16ceda89. */
9539 if (end > aux->info + aux->info_size)
9540 end = aux->info + aux->info_size;
9541 for (dp = head + 8; dp < end;)
9542 dp = unw_decode (dp, in_body, & in_body, end);
9545 free (aux->funtab);
9547 return res;
9550 static bool
9551 slurp_ia64_unwind_table (Filedata * filedata,
9552 struct ia64_unw_aux_info * aux,
9553 Elf_Internal_Shdr * sec)
9555 uint64_t size, nrelas, i;
9556 Elf_Internal_Phdr * seg;
9557 struct ia64_unw_table_entry * tep;
9558 Elf_Internal_Shdr * relsec;
9559 Elf_Internal_Rela * rela;
9560 Elf_Internal_Rela * rp;
9561 unsigned char * table;
9562 unsigned char * tp;
9563 Elf_Internal_Sym * sym;
9564 const char * relname;
9566 aux->table_len = 0;
9568 /* First, find the starting address of the segment that includes
9569 this section: */
9571 if (filedata->file_header.e_phnum)
9573 if (! get_program_headers (filedata))
9574 return false;
9576 for (seg = filedata->program_headers;
9577 seg < filedata->program_headers + filedata->file_header.e_phnum;
9578 ++seg)
9580 if (seg->p_type != PT_LOAD)
9581 continue;
9583 if (sec->sh_addr >= seg->p_vaddr
9584 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9586 aux->seg_base = seg->p_vaddr;
9587 break;
9592 /* Second, build the unwind table from the contents of the unwind section: */
9593 size = sec->sh_size;
9594 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
9595 _("unwind table"));
9596 if (!table)
9597 return false;
9599 aux->table_len = size / (3 * eh_addr_size);
9600 aux->table = (struct ia64_unw_table_entry *)
9601 xcmalloc (aux->table_len, sizeof (aux->table[0]));
9602 tep = aux->table;
9604 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
9606 tep->start.section = SHN_UNDEF;
9607 tep->end.section = SHN_UNDEF;
9608 tep->info.section = SHN_UNDEF;
9609 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9610 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9611 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9612 tep->start.offset += aux->seg_base;
9613 tep->end.offset += aux->seg_base;
9614 tep->info.offset += aux->seg_base;
9616 free (table);
9618 /* Third, apply any relocations to the unwind table: */
9619 for (relsec = filedata->section_headers;
9620 relsec < filedata->section_headers + filedata->file_header.e_shnum;
9621 ++relsec)
9623 if (relsec->sh_type != SHT_RELA
9624 || relsec->sh_info >= filedata->file_header.e_shnum
9625 || filedata->section_headers + relsec->sh_info != sec)
9626 continue;
9628 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
9629 & rela, & nrelas))
9631 free (aux->table);
9632 aux->table = NULL;
9633 aux->table_len = 0;
9634 return false;
9637 for (rp = rela; rp < rela + nrelas; ++rp)
9639 unsigned int sym_ndx;
9640 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9641 relname = elf_ia64_reloc_type (r_type);
9643 /* PR 17531: file: 9fa67536. */
9644 if (relname == NULL)
9646 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9647 continue;
9650 if (! startswith (relname, "R_IA64_SEGREL"))
9652 warn (_("Skipping unexpected relocation type: %s\n"), relname);
9653 continue;
9656 i = rp->r_offset / (3 * eh_addr_size);
9658 /* PR 17531: file: 5bc8d9bf. */
9659 if (i >= aux->table_len)
9661 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9663 continue;
9666 sym_ndx = get_reloc_symindex (rp->r_info);
9667 if (sym_ndx >= aux->nsyms)
9669 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9670 sym_ndx);
9671 continue;
9673 sym = aux->symtab + sym_ndx;
9675 switch (rp->r_offset / eh_addr_size % 3)
9677 case 0:
9678 aux->table[i].start.section = sym->st_shndx;
9679 aux->table[i].start.offset = rp->r_addend + sym->st_value;
9680 break;
9681 case 1:
9682 aux->table[i].end.section = sym->st_shndx;
9683 aux->table[i].end.offset = rp->r_addend + sym->st_value;
9684 break;
9685 case 2:
9686 aux->table[i].info.section = sym->st_shndx;
9687 aux->table[i].info.offset = rp->r_addend + sym->st_value;
9688 break;
9689 default:
9690 break;
9694 free (rela);
9697 return true;
9700 static bool
9701 ia64_process_unwind (Filedata * filedata)
9703 Elf_Internal_Shdr * sec;
9704 Elf_Internal_Shdr * unwsec = NULL;
9705 uint64_t i, unwcount = 0, unwstart = 0;
9706 struct ia64_unw_aux_info aux;
9707 bool res = true;
9709 memset (& aux, 0, sizeof (aux));
9711 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
9713 if (sec->sh_type == SHT_SYMTAB)
9715 if (aux.symtab)
9717 error (_("Multiple symbol tables encountered\n"));
9718 free (aux.symtab);
9719 aux.symtab = NULL;
9720 free (aux.strtab);
9721 aux.strtab = NULL;
9723 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9724 &aux.strtab, &aux.strtab_size))
9725 return false;
9727 else if (sec->sh_type == SHT_IA_64_UNWIND)
9728 unwcount++;
9731 if (!unwcount)
9732 printf (_("\nThere are no unwind sections in this file.\n"));
9734 while (unwcount-- > 0)
9736 const char *suffix;
9737 size_t len, len2;
9739 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
9740 i < filedata->file_header.e_shnum; ++i, ++sec)
9741 if (sec->sh_type == SHT_IA_64_UNWIND)
9743 unwsec = sec;
9744 break;
9746 /* We have already counted the number of SHT_IA64_UNWIND
9747 sections so the loop above should never fail. */
9748 assert (unwsec != NULL);
9750 unwstart = i + 1;
9751 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
9753 if ((unwsec->sh_flags & SHF_GROUP) != 0)
9755 /* We need to find which section group it is in. */
9756 struct group_list * g;
9758 if (filedata->section_headers_groups == NULL
9759 || filedata->section_headers_groups[i] == NULL)
9760 i = filedata->file_header.e_shnum;
9761 else
9763 g = filedata->section_headers_groups[i]->root;
9765 for (; g != NULL; g = g->next)
9767 sec = filedata->section_headers + g->section_index;
9769 if (section_name_valid (filedata, sec)
9770 && streq (section_name (filedata, sec),
9771 ELF_STRING_ia64_unwind_info))
9772 break;
9775 if (g == NULL)
9776 i = filedata->file_header.e_shnum;
9779 else if (section_name_valid (filedata, unwsec)
9780 && startswith (section_name (filedata, unwsec),
9781 ELF_STRING_ia64_unwind_once))
9783 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
9784 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
9785 suffix = section_name (filedata, unwsec) + len;
9786 for (i = 0, sec = filedata->section_headers;
9787 i < filedata->file_header.e_shnum;
9788 ++i, ++sec)
9789 if (section_name_valid (filedata, sec)
9790 && startswith (section_name (filedata, sec),
9791 ELF_STRING_ia64_unwind_info_once)
9792 && streq (section_name (filedata, sec) + len2, suffix))
9793 break;
9795 else
9797 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
9798 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
9799 len = sizeof (ELF_STRING_ia64_unwind) - 1;
9800 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
9801 suffix = "";
9802 if (section_name_valid (filedata, unwsec)
9803 && startswith (section_name (filedata, unwsec),
9804 ELF_STRING_ia64_unwind))
9805 suffix = section_name (filedata, unwsec) + len;
9806 for (i = 0, sec = filedata->section_headers;
9807 i < filedata->file_header.e_shnum;
9808 ++i, ++sec)
9809 if (section_name_valid (filedata, sec)
9810 && startswith (section_name (filedata, sec),
9811 ELF_STRING_ia64_unwind_info)
9812 && streq (section_name (filedata, sec) + len2, suffix))
9813 break;
9816 if (i == filedata->file_header.e_shnum)
9818 printf (_("\nCould not find unwind info section for "));
9820 if (filedata->string_table == NULL)
9821 printf ("%d", unwsec->sh_name);
9822 else
9823 printf ("'%s'", printable_section_name (filedata, unwsec));
9825 else
9827 aux.info_addr = sec->sh_addr;
9828 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
9829 sec->sh_size,
9830 _("unwind info"));
9831 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
9833 printf (_("\nUnwind section "));
9835 if (filedata->string_table == NULL)
9836 printf ("%d", unwsec->sh_name);
9837 else
9838 printf ("'%s'", printable_section_name (filedata, unwsec));
9840 printf (_(" at offset %#" PRIx64 " contains %" PRIu64 " entries:\n"),
9841 unwsec->sh_offset,
9842 unwsec->sh_size / (3 * eh_addr_size));
9844 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
9845 && aux.table_len > 0)
9846 dump_ia64_unwind (filedata, & aux);
9848 free ((char *) aux.table);
9849 free ((char *) aux.info);
9850 aux.table = NULL;
9851 aux.info = NULL;
9855 free (aux.symtab);
9856 free ((char *) aux.strtab);
9858 return res;
9861 struct hppa_unw_table_entry
9863 struct absaddr start;
9864 struct absaddr end;
9865 unsigned int Cannot_unwind:1; /* 0 */
9866 unsigned int Millicode:1; /* 1 */
9867 unsigned int Millicode_save_sr0:1; /* 2 */
9868 unsigned int Region_description:2; /* 3..4 */
9869 unsigned int reserved1:1; /* 5 */
9870 unsigned int Entry_SR:1; /* 6 */
9871 unsigned int Entry_FR:4; /* Number saved 7..10 */
9872 unsigned int Entry_GR:5; /* Number saved 11..15 */
9873 unsigned int Args_stored:1; /* 16 */
9874 unsigned int Variable_Frame:1; /* 17 */
9875 unsigned int Separate_Package_Body:1; /* 18 */
9876 unsigned int Frame_Extension_Millicode:1; /* 19 */
9877 unsigned int Stack_Overflow_Check:1; /* 20 */
9878 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
9879 unsigned int Ada_Region:1; /* 22 */
9880 unsigned int cxx_info:1; /* 23 */
9881 unsigned int cxx_try_catch:1; /* 24 */
9882 unsigned int sched_entry_seq:1; /* 25 */
9883 unsigned int reserved2:1; /* 26 */
9884 unsigned int Save_SP:1; /* 27 */
9885 unsigned int Save_RP:1; /* 28 */
9886 unsigned int Save_MRP_in_frame:1; /* 29 */
9887 unsigned int extn_ptr_defined:1; /* 30 */
9888 unsigned int Cleanup_defined:1; /* 31 */
9890 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
9891 unsigned int HP_UX_interrupt_marker:1; /* 1 */
9892 unsigned int Large_frame:1; /* 2 */
9893 unsigned int Pseudo_SP_Set:1; /* 3 */
9894 unsigned int reserved4:1; /* 4 */
9895 unsigned int Total_frame_size:27; /* 5..31 */
9898 struct hppa_unw_aux_info
9900 struct hppa_unw_table_entry * table; /* Unwind table. */
9901 uint64_t table_len; /* Length of unwind table. */
9902 uint64_t seg_base; /* Starting address of segment. */
9903 Elf_Internal_Sym * symtab; /* The symbol table. */
9904 uint64_t nsyms; /* Number of symbols. */
9905 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9906 uint64_t nfuns; /* Number of entries in funtab. */
9907 char * strtab; /* The string table. */
9908 uint64_t strtab_size; /* Size of string table. */
9911 static bool
9912 dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
9914 struct hppa_unw_table_entry * tp;
9915 uint64_t j, nfuns;
9916 bool res = true;
9918 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9919 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9920 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9921 aux->funtab[nfuns++] = aux->symtab[j];
9922 aux->nfuns = nfuns;
9923 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9925 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9927 uint64_t offset;
9928 const char * procname;
9930 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
9931 aux->strtab_size, tp->start, &procname,
9932 &offset);
9934 fputs ("\n<", stdout);
9936 if (procname)
9938 fputs (procname, stdout);
9940 if (offset)
9941 printf ("+%" PRIx64, offset);
9944 fputs (">: [", stdout);
9945 print_vma (tp->start.offset, PREFIX_HEX);
9946 fputc ('-', stdout);
9947 print_vma (tp->end.offset, PREFIX_HEX);
9948 printf ("]\n\t");
9950 #define PF(_m) if (tp->_m) printf (#_m " ");
9951 #define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
9952 PF(Cannot_unwind);
9953 PF(Millicode);
9954 PF(Millicode_save_sr0);
9955 /* PV(Region_description); */
9956 PF(Entry_SR);
9957 PV(Entry_FR);
9958 PV(Entry_GR);
9959 PF(Args_stored);
9960 PF(Variable_Frame);
9961 PF(Separate_Package_Body);
9962 PF(Frame_Extension_Millicode);
9963 PF(Stack_Overflow_Check);
9964 PF(Two_Instruction_SP_Increment);
9965 PF(Ada_Region);
9966 PF(cxx_info);
9967 PF(cxx_try_catch);
9968 PF(sched_entry_seq);
9969 PF(Save_SP);
9970 PF(Save_RP);
9971 PF(Save_MRP_in_frame);
9972 PF(extn_ptr_defined);
9973 PF(Cleanup_defined);
9974 PF(MPE_XL_interrupt_marker);
9975 PF(HP_UX_interrupt_marker);
9976 PF(Large_frame);
9977 PF(Pseudo_SP_Set);
9978 PV(Total_frame_size);
9979 #undef PF
9980 #undef PV
9983 printf ("\n");
9985 free (aux->funtab);
9987 return res;
9990 static bool
9991 slurp_hppa_unwind_table (Filedata * filedata,
9992 struct hppa_unw_aux_info * aux,
9993 Elf_Internal_Shdr * sec)
9995 uint64_t size, unw_ent_size, nentries, nrelas, i;
9996 Elf_Internal_Phdr * seg;
9997 struct hppa_unw_table_entry * tep;
9998 Elf_Internal_Shdr * relsec;
9999 Elf_Internal_Rela * rela;
10000 Elf_Internal_Rela * rp;
10001 unsigned char * table;
10002 unsigned char * tp;
10003 Elf_Internal_Sym * sym;
10004 const char * relname;
10006 /* First, find the starting address of the segment that includes
10007 this section. */
10008 if (filedata->file_header.e_phnum)
10010 if (! get_program_headers (filedata))
10011 return false;
10013 for (seg = filedata->program_headers;
10014 seg < filedata->program_headers + filedata->file_header.e_phnum;
10015 ++seg)
10017 if (seg->p_type != PT_LOAD)
10018 continue;
10020 if (sec->sh_addr >= seg->p_vaddr
10021 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
10023 aux->seg_base = seg->p_vaddr;
10024 break;
10029 /* Second, build the unwind table from the contents of the unwind
10030 section. */
10031 size = sec->sh_size;
10032 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
10033 _("unwind table"));
10034 if (!table)
10035 return false;
10037 unw_ent_size = 16;
10038 nentries = size / unw_ent_size;
10039 size = unw_ent_size * nentries;
10041 aux->table_len = nentries;
10042 tep = aux->table = (struct hppa_unw_table_entry *)
10043 xcmalloc (nentries, sizeof (aux->table[0]));
10045 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
10047 unsigned int tmp1, tmp2;
10049 tep->start.section = SHN_UNDEF;
10050 tep->end.section = SHN_UNDEF;
10052 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
10053 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
10054 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
10055 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
10057 tep->start.offset += aux->seg_base;
10058 tep->end.offset += aux->seg_base;
10060 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
10061 tep->Millicode = (tmp1 >> 30) & 0x1;
10062 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
10063 tep->Region_description = (tmp1 >> 27) & 0x3;
10064 tep->reserved1 = (tmp1 >> 26) & 0x1;
10065 tep->Entry_SR = (tmp1 >> 25) & 0x1;
10066 tep->Entry_FR = (tmp1 >> 21) & 0xf;
10067 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
10068 tep->Args_stored = (tmp1 >> 15) & 0x1;
10069 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
10070 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
10071 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
10072 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
10073 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
10074 tep->Ada_Region = (tmp1 >> 9) & 0x1;
10075 tep->cxx_info = (tmp1 >> 8) & 0x1;
10076 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
10077 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
10078 tep->reserved2 = (tmp1 >> 5) & 0x1;
10079 tep->Save_SP = (tmp1 >> 4) & 0x1;
10080 tep->Save_RP = (tmp1 >> 3) & 0x1;
10081 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
10082 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
10083 tep->Cleanup_defined = tmp1 & 0x1;
10085 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
10086 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
10087 tep->Large_frame = (tmp2 >> 29) & 0x1;
10088 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
10089 tep->reserved4 = (tmp2 >> 27) & 0x1;
10090 tep->Total_frame_size = tmp2 & 0x7ffffff;
10092 free (table);
10094 /* Third, apply any relocations to the unwind table. */
10095 for (relsec = filedata->section_headers;
10096 relsec < filedata->section_headers + filedata->file_header.e_shnum;
10097 ++relsec)
10099 if (relsec->sh_type != SHT_RELA
10100 || relsec->sh_info >= filedata->file_header.e_shnum
10101 || filedata->section_headers + relsec->sh_info != sec)
10102 continue;
10104 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
10105 & rela, & nrelas))
10106 return false;
10108 for (rp = rela; rp < rela + nrelas; ++rp)
10110 unsigned int sym_ndx;
10111 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
10112 relname = elf_hppa_reloc_type (r_type);
10114 if (relname == NULL)
10116 warn (_("Skipping unknown relocation type: %u\n"), r_type);
10117 continue;
10120 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
10121 if (! startswith (relname, "R_PARISC_SEGREL"))
10123 warn (_("Skipping unexpected relocation type: %s\n"), relname);
10124 continue;
10127 i = rp->r_offset / unw_ent_size;
10128 if (i >= aux->table_len)
10130 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
10132 continue;
10135 sym_ndx = get_reloc_symindex (rp->r_info);
10136 if (sym_ndx >= aux->nsyms)
10138 warn (_("Skipping reloc with invalid symbol index: %u\n"),
10139 sym_ndx);
10140 continue;
10142 sym = aux->symtab + sym_ndx;
10144 switch ((rp->r_offset % unw_ent_size) / 4)
10146 case 0:
10147 aux->table[i].start.section = sym->st_shndx;
10148 aux->table[i].start.offset = sym->st_value + rp->r_addend;
10149 break;
10150 case 1:
10151 aux->table[i].end.section = sym->st_shndx;
10152 aux->table[i].end.offset = sym->st_value + rp->r_addend;
10153 break;
10154 default:
10155 break;
10159 free (rela);
10162 return true;
10165 static bool
10166 hppa_process_unwind (Filedata * filedata)
10168 struct hppa_unw_aux_info aux;
10169 Elf_Internal_Shdr * unwsec = NULL;
10170 Elf_Internal_Shdr * sec;
10171 size_t i;
10172 bool res = true;
10174 if (filedata->string_table == NULL)
10175 return false;
10177 memset (& aux, 0, sizeof (aux));
10179 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
10181 if (sec->sh_type == SHT_SYMTAB)
10183 if (aux.symtab)
10185 error (_("Multiple symbol tables encountered\n"));
10186 free (aux.symtab);
10187 aux.symtab = NULL;
10188 free (aux.strtab);
10189 aux.strtab = NULL;
10191 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10192 &aux.strtab, &aux.strtab_size))
10193 return false;
10195 else if (section_name_valid (filedata, sec)
10196 && streq (section_name (filedata, sec), ".PARISC.unwind"))
10197 unwsec = sec;
10200 if (!unwsec)
10201 printf (_("\nThere are no unwind sections in this file.\n"));
10203 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
10205 if (section_name_valid (filedata, sec)
10206 && streq (section_name (filedata, sec), ".PARISC.unwind"))
10208 uint64_t num_unwind = sec->sh_size / 16;
10210 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
10211 "contains %" PRIu64 " entry:\n",
10212 "\nUnwind section '%s' at offset %#" PRIx64 " "
10213 "contains %" PRIu64 " entries:\n",
10214 num_unwind),
10215 printable_section_name (filedata, sec),
10216 sec->sh_offset,
10217 num_unwind);
10219 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
10220 res = false;
10222 if (res && aux.table_len > 0)
10224 if (! dump_hppa_unwind (filedata, &aux))
10225 res = false;
10228 free ((char *) aux.table);
10229 aux.table = NULL;
10233 free (aux.symtab);
10234 free ((char *) aux.strtab);
10236 return res;
10239 struct arm_section
10241 unsigned char * data; /* The unwind data. */
10242 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
10243 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
10244 uint64_t nrelas; /* The number of relocations. */
10245 unsigned int rel_type; /* REL or RELA ? */
10246 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
10249 struct arm_unw_aux_info
10251 Filedata * filedata; /* The file containing the unwind sections. */
10252 Elf_Internal_Sym * symtab; /* The file's symbol table. */
10253 uint64_t nsyms; /* Number of symbols. */
10254 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
10255 uint64_t nfuns; /* Number of these symbols. */
10256 char * strtab; /* The file's string table. */
10257 uint64_t strtab_size; /* Size of string table. */
10260 static const char *
10261 arm_print_vma_and_name (Filedata * filedata,
10262 struct arm_unw_aux_info * aux,
10263 uint64_t fn,
10264 struct absaddr addr)
10266 const char *procname;
10267 uint64_t sym_offset;
10269 if (addr.section == SHN_UNDEF)
10270 addr.offset = fn;
10272 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
10273 aux->strtab_size, addr, &procname,
10274 &sym_offset);
10276 print_vma (fn, PREFIX_HEX);
10278 if (procname)
10280 fputs (" <", stdout);
10281 fputs (procname, stdout);
10283 if (sym_offset)
10284 printf ("+0x%" PRIx64, sym_offset);
10285 fputc ('>', stdout);
10288 return procname;
10291 static void
10292 arm_free_section (struct arm_section *arm_sec)
10294 free (arm_sec->data);
10295 free (arm_sec->rela);
10298 /* 1) If SEC does not match the one cached in ARM_SEC, then free the current
10299 cached section and install SEC instead.
10300 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
10301 and return its valued in * WORDP, relocating if necessary.
10302 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
10303 relocation's offset in ADDR.
10304 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
10305 into the string table of the symbol associated with the reloc. If no
10306 reloc was applied store -1 there.
10307 5) Return TRUE upon success, FALSE otherwise. */
10309 static bool
10310 get_unwind_section_word (Filedata * filedata,
10311 struct arm_unw_aux_info * aux,
10312 struct arm_section * arm_sec,
10313 Elf_Internal_Shdr * sec,
10314 uint64_t word_offset,
10315 unsigned int * wordp,
10316 struct absaddr * addr,
10317 uint64_t * sym_name)
10319 Elf_Internal_Rela *rp;
10320 Elf_Internal_Sym *sym;
10321 const char * relname;
10322 unsigned int word;
10323 bool wrapped;
10325 if (sec == NULL || arm_sec == NULL)
10326 return false;
10328 addr->section = SHN_UNDEF;
10329 addr->offset = 0;
10331 if (sym_name != NULL)
10332 *sym_name = (uint64_t) -1;
10334 /* If necessary, update the section cache. */
10335 if (sec != arm_sec->sec)
10337 Elf_Internal_Shdr *relsec;
10339 arm_free_section (arm_sec);
10341 arm_sec->sec = sec;
10342 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
10343 sec->sh_size, _("unwind data"));
10344 arm_sec->rela = NULL;
10345 arm_sec->nrelas = 0;
10347 for (relsec = filedata->section_headers;
10348 relsec < filedata->section_headers + filedata->file_header.e_shnum;
10349 ++relsec)
10351 if (relsec->sh_info >= filedata->file_header.e_shnum
10352 || filedata->section_headers + relsec->sh_info != sec
10353 /* PR 15745: Check the section type as well. */
10354 || (relsec->sh_type != SHT_REL
10355 && relsec->sh_type != SHT_RELA))
10356 continue;
10358 arm_sec->rel_type = relsec->sh_type;
10359 if (relsec->sh_type == SHT_REL)
10361 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
10362 relsec->sh_size,
10363 & arm_sec->rela, & arm_sec->nrelas))
10364 return false;
10366 else /* relsec->sh_type == SHT_RELA */
10368 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
10369 relsec->sh_size,
10370 & arm_sec->rela, & arm_sec->nrelas))
10371 return false;
10373 break;
10376 arm_sec->next_rela = arm_sec->rela;
10379 /* If there is no unwind data we can do nothing. */
10380 if (arm_sec->data == NULL)
10381 return false;
10383 /* If the offset is invalid then fail. */
10384 if (/* PR 21343 *//* PR 18879 */
10385 sec->sh_size < 4
10386 || word_offset > sec->sh_size - 4)
10387 return false;
10389 /* Get the word at the required offset. */
10390 word = byte_get (arm_sec->data + word_offset, 4);
10392 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
10393 if (arm_sec->rela == NULL)
10395 * wordp = word;
10396 return true;
10399 /* Look through the relocs to find the one that applies to the provided offset. */
10400 wrapped = false;
10401 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
10403 uint64_t prelval, offset;
10405 if (rp->r_offset > word_offset && !wrapped)
10407 rp = arm_sec->rela;
10408 wrapped = true;
10410 if (rp->r_offset > word_offset)
10411 break;
10413 if (rp->r_offset & 3)
10415 warn (_("Skipping unexpected relocation at offset %#" PRIx64 "\n"),
10416 rp->r_offset);
10417 continue;
10420 if (rp->r_offset < word_offset)
10421 continue;
10423 /* PR 17531: file: 027-161405-0.004 */
10424 if (aux->symtab == NULL)
10425 continue;
10427 if (arm_sec->rel_type == SHT_REL)
10429 offset = word & 0x7fffffff;
10430 if (offset & 0x40000000)
10431 offset |= ~ (uint64_t) 0x7fffffff;
10433 else if (arm_sec->rel_type == SHT_RELA)
10434 offset = rp->r_addend;
10435 else
10437 error (_("Unknown section relocation type %d encountered\n"),
10438 arm_sec->rel_type);
10439 break;
10442 /* PR 17531 file: 027-1241568-0.004. */
10443 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
10445 error (_("Bad symbol index in unwind relocation "
10446 "(%" PRIu64 " > %" PRIu64 ")\n"),
10447 ELF32_R_SYM (rp->r_info), aux->nsyms);
10448 break;
10451 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
10452 offset += sym->st_value;
10453 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
10455 /* Check that we are processing the expected reloc type. */
10456 if (filedata->file_header.e_machine == EM_ARM)
10458 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
10459 if (relname == NULL)
10461 warn (_("Skipping unknown ARM relocation type: %d\n"),
10462 (int) ELF32_R_TYPE (rp->r_info));
10463 continue;
10466 if (streq (relname, "R_ARM_NONE"))
10467 continue;
10469 if (! streq (relname, "R_ARM_PREL31"))
10471 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
10472 continue;
10475 else if (filedata->file_header.e_machine == EM_TI_C6000)
10477 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
10478 if (relname == NULL)
10480 warn (_("Skipping unknown C6000 relocation type: %d\n"),
10481 (int) ELF32_R_TYPE (rp->r_info));
10482 continue;
10485 if (streq (relname, "R_C6000_NONE"))
10486 continue;
10488 if (! streq (relname, "R_C6000_PREL31"))
10490 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
10491 continue;
10494 prelval >>= 1;
10496 else
10498 /* This function currently only supports ARM and TI unwinders. */
10499 warn (_("Only TI and ARM unwinders are currently supported\n"));
10500 break;
10503 word = (word & ~ (uint64_t) 0x7fffffff) | (prelval & 0x7fffffff);
10504 addr->section = sym->st_shndx;
10505 addr->offset = offset;
10507 if (sym_name)
10508 * sym_name = sym->st_name;
10509 break;
10512 *wordp = word;
10513 arm_sec->next_rela = rp;
10515 return true;
10518 static const char *tic6x_unwind_regnames[16] =
10520 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
10521 "A14", "A13", "A12", "A11", "A10",
10522 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
10525 static void
10526 decode_tic6x_unwind_regmask (unsigned int mask)
10528 int i;
10530 for (i = 12; mask; mask >>= 1, i--)
10532 if (mask & 1)
10534 fputs (tic6x_unwind_regnames[i], stdout);
10535 if (mask > 1)
10536 fputs (", ", stdout);
10541 #define ADVANCE \
10542 if (remaining == 0 && more_words) \
10544 data_offset += 4; \
10545 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
10546 data_offset, & word, & addr, NULL)) \
10547 return false; \
10548 remaining = 4; \
10549 more_words--; \
10552 #define GET_OP(OP) \
10553 ADVANCE; \
10554 if (remaining) \
10556 remaining--; \
10557 (OP) = word >> 24; \
10558 word <<= 8; \
10560 else \
10562 printf (_("[Truncated opcode]\n")); \
10563 return false; \
10565 printf ("0x%02x ", OP)
10567 static bool
10568 decode_arm_unwind_bytecode (Filedata * filedata,
10569 struct arm_unw_aux_info * aux,
10570 unsigned int word,
10571 unsigned int remaining,
10572 unsigned int more_words,
10573 uint64_t data_offset,
10574 Elf_Internal_Shdr * data_sec,
10575 struct arm_section * data_arm_sec)
10577 struct absaddr addr;
10578 bool res = true;
10580 /* Decode the unwinding instructions. */
10581 while (1)
10583 unsigned int op, op2;
10585 ADVANCE;
10586 if (remaining == 0)
10587 break;
10588 remaining--;
10589 op = word >> 24;
10590 word <<= 8;
10592 printf (" 0x%02x ", op);
10594 if ((op & 0xc0) == 0x00)
10596 int offset = ((op & 0x3f) << 2) + 4;
10598 printf (" vsp = vsp + %d", offset);
10600 else if ((op & 0xc0) == 0x40)
10602 int offset = ((op & 0x3f) << 2) + 4;
10604 printf (" vsp = vsp - %d", offset);
10606 else if ((op & 0xf0) == 0x80)
10608 GET_OP (op2);
10609 if (op == 0x80 && op2 == 0)
10610 printf (_("Refuse to unwind"));
10611 else
10613 unsigned int mask = ((op & 0x0f) << 8) | op2;
10614 bool first = true;
10615 int i;
10617 printf ("pop {");
10618 for (i = 0; i < 12; i++)
10619 if (mask & (1 << i))
10621 if (first)
10622 first = false;
10623 else
10624 printf (", ");
10625 printf ("r%d", 4 + i);
10627 printf ("}");
10630 else if ((op & 0xf0) == 0x90)
10632 if (op == 0x9d || op == 0x9f)
10633 printf (_(" [Reserved]"));
10634 else
10635 printf (" vsp = r%d", op & 0x0f);
10637 else if ((op & 0xf0) == 0xa0)
10639 int end = 4 + (op & 0x07);
10640 bool first = true;
10641 int i;
10643 printf (" pop {");
10644 for (i = 4; i <= end; i++)
10646 if (first)
10647 first = false;
10648 else
10649 printf (", ");
10650 printf ("r%d", i);
10652 if (op & 0x08)
10654 if (!first)
10655 printf (", ");
10656 printf ("r14");
10658 printf ("}");
10660 else if (op == 0xb0)
10661 printf (_(" finish"));
10662 else if (op == 0xb1)
10664 GET_OP (op2);
10665 if (op2 == 0 || (op2 & 0xf0) != 0)
10666 printf (_("[Spare]"));
10667 else
10669 unsigned int mask = op2 & 0x0f;
10670 bool first = true;
10671 int i;
10673 printf ("pop {");
10674 for (i = 0; i < 12; i++)
10675 if (mask & (1 << i))
10677 if (first)
10678 first = false;
10679 else
10680 printf (", ");
10681 printf ("r%d", i);
10683 printf ("}");
10686 else if (op == 0xb2)
10688 unsigned char buf[9];
10689 unsigned int i, len;
10690 uint64_t offset;
10692 for (i = 0; i < sizeof (buf); i++)
10694 GET_OP (buf[i]);
10695 if ((buf[i] & 0x80) == 0)
10696 break;
10698 if (i == sizeof (buf))
10700 error (_("corrupt change to vsp\n"));
10701 res = false;
10703 else
10705 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
10706 assert (len == i + 1);
10707 offset = offset * 4 + 0x204;
10708 printf ("vsp = vsp + %" PRId64, offset);
10711 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
10713 unsigned int first, last;
10715 GET_OP (op2);
10716 first = op2 >> 4;
10717 last = op2 & 0x0f;
10718 if (op == 0xc8)
10719 first = first + 16;
10720 printf ("pop {D%d", first);
10721 if (last)
10722 printf ("-D%d", first + last);
10723 printf ("}");
10725 else if (op == 0xb4)
10726 printf (_(" pop {ra_auth_code}"));
10727 else if (op == 0xb5)
10728 printf (_(" vsp as modifier for PAC validation"));
10729 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
10731 unsigned int count = op & 0x07;
10733 printf ("pop {D8");
10734 if (count)
10735 printf ("-D%d", 8 + count);
10736 printf ("}");
10738 else if (op >= 0xc0 && op <= 0xc5)
10740 unsigned int count = op & 0x07;
10742 printf (" pop {wR10");
10743 if (count)
10744 printf ("-wR%d", 10 + count);
10745 printf ("}");
10747 else if (op == 0xc6)
10749 unsigned int first, last;
10751 GET_OP (op2);
10752 first = op2 >> 4;
10753 last = op2 & 0x0f;
10754 printf ("pop {wR%d", first);
10755 if (last)
10756 printf ("-wR%d", first + last);
10757 printf ("}");
10759 else if (op == 0xc7)
10761 GET_OP (op2);
10762 if (op2 == 0 || (op2 & 0xf0) != 0)
10763 printf (_("[Spare]"));
10764 else
10766 unsigned int mask = op2 & 0x0f;
10767 bool first = true;
10768 int i;
10770 printf ("pop {");
10771 for (i = 0; i < 4; i++)
10772 if (mask & (1 << i))
10774 if (first)
10775 first = false;
10776 else
10777 printf (", ");
10778 printf ("wCGR%d", i);
10780 printf ("}");
10783 else
10785 printf (_(" [unsupported opcode]"));
10786 res = false;
10789 printf ("\n");
10792 return res;
10795 static bool
10796 decode_tic6x_unwind_bytecode (Filedata * filedata,
10797 struct arm_unw_aux_info * aux,
10798 unsigned int word,
10799 unsigned int remaining,
10800 unsigned int more_words,
10801 uint64_t data_offset,
10802 Elf_Internal_Shdr * data_sec,
10803 struct arm_section * data_arm_sec)
10805 struct absaddr addr;
10807 /* Decode the unwinding instructions. */
10808 while (1)
10810 unsigned int op, op2;
10812 ADVANCE;
10813 if (remaining == 0)
10814 break;
10815 remaining--;
10816 op = word >> 24;
10817 word <<= 8;
10819 printf (" 0x%02x ", op);
10821 if ((op & 0xc0) == 0x00)
10823 int offset = ((op & 0x3f) << 3) + 8;
10824 printf (" sp = sp + %d", offset);
10826 else if ((op & 0xc0) == 0x80)
10828 GET_OP (op2);
10829 if (op == 0x80 && op2 == 0)
10830 printf (_("Refuse to unwind"));
10831 else
10833 unsigned int mask = ((op & 0x1f) << 8) | op2;
10834 if (op & 0x20)
10835 printf ("pop compact {");
10836 else
10837 printf ("pop {");
10839 decode_tic6x_unwind_regmask (mask);
10840 printf("}");
10843 else if ((op & 0xf0) == 0xc0)
10845 unsigned int reg;
10846 unsigned int nregs;
10847 unsigned int i;
10848 const char *name;
10849 struct
10851 unsigned int offset;
10852 unsigned int reg;
10853 } regpos[16];
10855 /* Scan entire instruction first so that GET_OP output is not
10856 interleaved with disassembly. */
10857 nregs = 0;
10858 for (i = 0; nregs < (op & 0xf); i++)
10860 GET_OP (op2);
10861 reg = op2 >> 4;
10862 if (reg != 0xf)
10864 regpos[nregs].offset = i * 2;
10865 regpos[nregs].reg = reg;
10866 nregs++;
10869 reg = op2 & 0xf;
10870 if (reg != 0xf)
10872 regpos[nregs].offset = i * 2 + 1;
10873 regpos[nregs].reg = reg;
10874 nregs++;
10878 printf (_("pop frame {"));
10879 if (nregs == 0)
10881 printf (_("*corrupt* - no registers specified"));
10883 else
10885 reg = nregs - 1;
10886 for (i = i * 2; i > 0; i--)
10888 if (regpos[reg].offset == i - 1)
10890 name = tic6x_unwind_regnames[regpos[reg].reg];
10891 if (reg > 0)
10892 reg--;
10894 else
10895 name = _("[pad]");
10897 fputs (name, stdout);
10898 if (i > 1)
10899 printf (", ");
10903 printf ("}");
10905 else if (op == 0xd0)
10906 printf (" MOV FP, SP");
10907 else if (op == 0xd1)
10908 printf (" __c6xabi_pop_rts");
10909 else if (op == 0xd2)
10911 unsigned char buf[9];
10912 unsigned int i, len;
10913 uint64_t offset;
10915 for (i = 0; i < sizeof (buf); i++)
10917 GET_OP (buf[i]);
10918 if ((buf[i] & 0x80) == 0)
10919 break;
10921 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10922 if (i == sizeof (buf))
10924 warn (_("Corrupt stack pointer adjustment detected\n"));
10925 return false;
10928 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
10929 assert (len == i + 1);
10930 offset = offset * 8 + 0x408;
10931 printf (_("sp = sp + %" PRId64), offset);
10933 else if ((op & 0xf0) == 0xe0)
10935 if ((op & 0x0f) == 7)
10936 printf (" RETURN");
10937 else
10938 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10940 else
10942 printf (_(" [unsupported opcode]"));
10944 putchar ('\n');
10947 return true;
10950 static uint64_t
10951 arm_expand_prel31 (Filedata * filedata, uint64_t word, uint64_t where)
10953 uint64_t offset;
10955 offset = word & 0x7fffffff;
10956 if (offset & 0x40000000)
10957 offset |= ~ (uint64_t) 0x7fffffff;
10959 if (filedata->file_header.e_machine == EM_TI_C6000)
10960 offset <<= 1;
10962 return offset + where;
10965 static bool
10966 decode_arm_unwind (Filedata * filedata,
10967 struct arm_unw_aux_info * aux,
10968 unsigned int word,
10969 unsigned int remaining,
10970 uint64_t data_offset,
10971 Elf_Internal_Shdr * data_sec,
10972 struct arm_section * data_arm_sec)
10974 int per_index;
10975 unsigned int more_words = 0;
10976 struct absaddr addr;
10977 uint64_t sym_name = (uint64_t) -1;
10978 bool res = true;
10980 if (remaining == 0)
10982 /* Fetch the first word.
10983 Note - when decoding an object file the address extracted
10984 here will always be 0. So we also pass in the sym_name
10985 parameter so that we can find the symbol associated with
10986 the personality routine. */
10987 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
10988 & word, & addr, & sym_name))
10989 return false;
10991 remaining = 4;
10993 else
10995 addr.section = SHN_UNDEF;
10996 addr.offset = 0;
10999 if ((word & 0x80000000) == 0)
11001 /* Expand prel31 for personality routine. */
11002 uint64_t fn;
11003 const char *procname;
11005 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
11006 printf (_(" Personality routine: "));
11007 if (fn == 0
11008 && addr.section == SHN_UNDEF && addr.offset == 0
11009 && sym_name != (uint64_t) -1 && sym_name < aux->strtab_size)
11011 procname = aux->strtab + sym_name;
11012 print_vma (fn, PREFIX_HEX);
11013 if (procname)
11015 fputs (" <", stdout);
11016 fputs (procname, stdout);
11017 fputc ('>', stdout);
11020 else
11021 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
11022 fputc ('\n', stdout);
11024 /* The GCC personality routines use the standard compact
11025 encoding, starting with one byte giving the number of
11026 words. */
11027 if (procname != NULL
11028 && (startswith (procname, "__gcc_personality_v0")
11029 || startswith (procname, "__gxx_personality_v0")
11030 || startswith (procname, "__gcj_personality_v0")
11031 || startswith (procname, "__gnu_objc_personality_v0")))
11033 remaining = 0;
11034 more_words = 1;
11035 ADVANCE;
11036 if (!remaining)
11038 printf (_(" [Truncated data]\n"));
11039 return false;
11041 more_words = word >> 24;
11042 word <<= 8;
11043 remaining--;
11044 per_index = -1;
11046 else
11047 return true;
11049 else
11051 /* ARM EHABI Section 6.3:
11053 An exception-handling table entry for the compact model looks like:
11055 31 30-28 27-24 23-0
11056 -- ----- ----- ----
11057 1 0 index Data for personalityRoutine[index] */
11059 if (filedata->file_header.e_machine == EM_ARM
11060 && (word & 0x70000000))
11062 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
11063 res = false;
11066 per_index = (word >> 24) & 0x7f;
11067 printf (_(" Compact model index: %d\n"), per_index);
11068 if (per_index == 0)
11070 more_words = 0;
11071 word <<= 8;
11072 remaining--;
11074 else if (per_index < 3)
11076 more_words = (word >> 16) & 0xff;
11077 word <<= 16;
11078 remaining -= 2;
11082 switch (filedata->file_header.e_machine)
11084 case EM_ARM:
11085 if (per_index < 3)
11087 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
11088 data_offset, data_sec, data_arm_sec))
11089 res = false;
11091 else
11093 warn (_("Unknown ARM compact model index encountered\n"));
11094 printf (_(" [reserved]\n"));
11095 res = false;
11097 break;
11099 case EM_TI_C6000:
11100 if (per_index < 3)
11102 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
11103 data_offset, data_sec, data_arm_sec))
11104 res = false;
11106 else if (per_index < 5)
11108 if (((word >> 17) & 0x7f) == 0x7f)
11109 printf (_(" Restore stack from frame pointer\n"));
11110 else
11111 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
11112 printf (_(" Registers restored: "));
11113 if (per_index == 4)
11114 printf (" (compact) ");
11115 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
11116 putchar ('\n');
11117 printf (_(" Return register: %s\n"),
11118 tic6x_unwind_regnames[word & 0xf]);
11120 else
11121 printf (_(" [reserved (%d)]\n"), per_index);
11122 break;
11124 default:
11125 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
11126 filedata->file_header.e_machine);
11127 res = false;
11130 /* Decode the descriptors. Not implemented. */
11132 return res;
11135 static bool
11136 dump_arm_unwind (Filedata * filedata,
11137 struct arm_unw_aux_info * aux,
11138 Elf_Internal_Shdr * exidx_sec)
11140 struct arm_section exidx_arm_sec, extab_arm_sec;
11141 unsigned int i, exidx_len;
11142 uint64_t j, nfuns;
11143 bool res = true;
11145 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
11146 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
11147 exidx_len = exidx_sec->sh_size / 8;
11149 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
11150 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
11151 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
11152 aux->funtab[nfuns++] = aux->symtab[j];
11153 aux->nfuns = nfuns;
11154 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
11156 for (i = 0; i < exidx_len; i++)
11158 unsigned int exidx_fn, exidx_entry;
11159 struct absaddr fn_addr, entry_addr;
11160 uint64_t fn;
11162 fputc ('\n', stdout);
11164 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
11165 8 * i, & exidx_fn, & fn_addr, NULL)
11166 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
11167 8 * i + 4, & exidx_entry, & entry_addr, NULL))
11169 free (aux->funtab);
11170 arm_free_section (& exidx_arm_sec);
11171 arm_free_section (& extab_arm_sec);
11172 return false;
11175 /* ARM EHABI, Section 5:
11176 An index table entry consists of 2 words.
11177 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
11178 if (exidx_fn & 0x80000000)
11180 warn (_("corrupt index table entry: %x\n"), exidx_fn);
11181 res = false;
11184 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
11186 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
11187 fputs (": ", stdout);
11189 if (exidx_entry == 1)
11191 print_vma (exidx_entry, PREFIX_HEX);
11192 fputs (" [cantunwind]\n", stdout);
11194 else if (exidx_entry & 0x80000000)
11196 print_vma (exidx_entry, PREFIX_HEX);
11197 fputc ('\n', stdout);
11198 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
11200 else
11202 uint64_t table, table_offset = 0;
11203 Elf_Internal_Shdr *table_sec;
11205 fputs ("@", stdout);
11206 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
11207 print_vma (table, PREFIX_HEX);
11208 printf ("\n");
11210 /* Locate the matching .ARM.extab. */
11211 if (entry_addr.section != SHN_UNDEF
11212 && entry_addr.section < filedata->file_header.e_shnum)
11214 table_sec = filedata->section_headers + entry_addr.section;
11215 table_offset = entry_addr.offset;
11216 /* PR 18879 */
11217 if (table_offset > table_sec->sh_size)
11219 warn (_("Unwind entry contains corrupt offset (%#" PRIx64 ") into section %s\n"),
11220 table_offset,
11221 printable_section_name (filedata, table_sec));
11222 res = false;
11223 continue;
11226 else
11228 table_sec = find_section_by_address (filedata, table);
11229 if (table_sec != NULL)
11230 table_offset = table - table_sec->sh_addr;
11233 if (table_sec == NULL)
11235 warn (_("Could not locate .ARM.extab section containing %#" PRIx64 ".\n"),
11236 table);
11237 res = false;
11238 continue;
11241 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
11242 &extab_arm_sec))
11243 res = false;
11247 printf ("\n");
11249 free (aux->funtab);
11250 arm_free_section (&exidx_arm_sec);
11251 arm_free_section (&extab_arm_sec);
11253 return res;
11256 /* Used for both ARM and C6X unwinding tables. */
11258 static bool
11259 arm_process_unwind (Filedata * filedata)
11261 struct arm_unw_aux_info aux;
11262 Elf_Internal_Shdr *unwsec = NULL;
11263 Elf_Internal_Shdr *sec;
11264 size_t i;
11265 unsigned int sec_type;
11266 bool res = true;
11268 switch (filedata->file_header.e_machine)
11270 case EM_ARM:
11271 sec_type = SHT_ARM_EXIDX;
11272 break;
11274 case EM_TI_C6000:
11275 sec_type = SHT_C6000_UNWIND;
11276 break;
11278 default:
11279 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
11280 filedata->file_header.e_machine);
11281 return false;
11284 if (filedata->string_table == NULL)
11285 return false;
11287 memset (& aux, 0, sizeof (aux));
11288 aux.filedata = filedata;
11290 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
11292 if (sec->sh_type == SHT_SYMTAB)
11294 if (aux.symtab)
11296 error (_("Multiple symbol tables encountered\n"));
11297 free (aux.symtab);
11298 aux.symtab = NULL;
11299 free (aux.strtab);
11300 aux.strtab = NULL;
11302 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
11303 &aux.strtab, &aux.strtab_size))
11304 return false;
11306 else if (sec->sh_type == sec_type)
11307 unwsec = sec;
11310 if (unwsec == NULL)
11311 printf (_("\nThere are no unwind sections in this file.\n"));
11312 else
11313 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
11315 if (sec->sh_type == sec_type)
11317 uint64_t num_unwind = sec->sh_size / (2 * eh_addr_size);
11318 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
11319 "contains %" PRIu64 " entry:\n",
11320 "\nUnwind section '%s' at offset %#" PRIx64 " "
11321 "contains %" PRIu64 " entries:\n",
11322 num_unwind),
11323 printable_section_name (filedata, sec),
11324 sec->sh_offset,
11325 num_unwind);
11327 if (! dump_arm_unwind (filedata, &aux, sec))
11328 res = false;
11332 free (aux.symtab);
11333 free ((char *) aux.strtab);
11335 return res;
11338 static bool
11339 no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
11341 printf (_("No processor specific unwind information to decode\n"));
11342 return true;
11345 static bool
11346 process_unwind (Filedata * filedata)
11348 struct unwind_handler
11350 unsigned int machtype;
11351 bool (* handler)(Filedata *);
11352 } handlers[] =
11354 { EM_ARM, arm_process_unwind },
11355 { EM_IA_64, ia64_process_unwind },
11356 { EM_PARISC, hppa_process_unwind },
11357 { EM_TI_C6000, arm_process_unwind },
11358 { EM_386, no_processor_specific_unwind },
11359 { EM_X86_64, no_processor_specific_unwind },
11360 { 0, NULL }
11362 int i;
11364 if (!do_unwind)
11365 return true;
11367 for (i = 0; handlers[i].handler != NULL; i++)
11368 if (filedata->file_header.e_machine == handlers[i].machtype)
11369 return handlers[i].handler (filedata);
11371 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
11372 get_machine_name (filedata->file_header.e_machine));
11373 return true;
11376 static void
11377 dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
11379 switch (entry->d_tag)
11381 case DT_AARCH64_BTI_PLT:
11382 case DT_AARCH64_PAC_PLT:
11383 break;
11384 default:
11385 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11386 break;
11388 putchar ('\n');
11391 static void
11392 dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
11394 switch (entry->d_tag)
11396 case DT_MIPS_FLAGS:
11397 if (entry->d_un.d_val == 0)
11398 printf (_("NONE"));
11399 else
11401 static const char * opts[] =
11403 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
11404 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
11405 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
11406 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
11407 "RLD_ORDER_SAFE"
11409 unsigned int cnt;
11410 bool first = true;
11412 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
11413 if (entry->d_un.d_val & (1 << cnt))
11415 printf ("%s%s", first ? "" : " ", opts[cnt]);
11416 first = false;
11419 break;
11421 case DT_MIPS_IVERSION:
11422 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11423 printf (_("Interface Version: %s"),
11424 get_dynamic_name (filedata, entry->d_un.d_val));
11425 else
11426 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
11427 entry->d_un.d_ptr);
11428 break;
11430 case DT_MIPS_TIME_STAMP:
11432 char timebuf[128];
11433 struct tm * tmp;
11434 time_t atime = entry->d_un.d_val;
11436 tmp = gmtime (&atime);
11437 /* PR 17531: file: 6accc532. */
11438 if (tmp == NULL)
11439 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
11440 else
11441 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
11442 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11443 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
11444 printf (_("Time Stamp: %s"), timebuf);
11446 break;
11448 case DT_MIPS_RLD_VERSION:
11449 case DT_MIPS_LOCAL_GOTNO:
11450 case DT_MIPS_CONFLICTNO:
11451 case DT_MIPS_LIBLISTNO:
11452 case DT_MIPS_SYMTABNO:
11453 case DT_MIPS_UNREFEXTNO:
11454 case DT_MIPS_HIPAGENO:
11455 case DT_MIPS_DELTA_CLASS_NO:
11456 case DT_MIPS_DELTA_INSTANCE_NO:
11457 case DT_MIPS_DELTA_RELOC_NO:
11458 case DT_MIPS_DELTA_SYM_NO:
11459 case DT_MIPS_DELTA_CLASSSYM_NO:
11460 case DT_MIPS_COMPACT_SIZE:
11461 print_vma (entry->d_un.d_val, DEC);
11462 break;
11464 case DT_MIPS_XHASH:
11465 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11466 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
11467 /* Falls through. */
11469 default:
11470 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11472 putchar ('\n');
11475 static void
11476 dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
11478 switch (entry->d_tag)
11480 case DT_HP_DLD_FLAGS:
11482 static struct
11484 unsigned int bit;
11485 const char * str;
11487 flags[] =
11489 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
11490 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
11491 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
11492 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
11493 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
11494 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
11495 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
11496 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
11497 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
11498 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
11499 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
11500 { DT_HP_GST, "HP_GST" },
11501 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
11502 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
11503 { DT_HP_NODELETE, "HP_NODELETE" },
11504 { DT_HP_GROUP, "HP_GROUP" },
11505 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
11507 bool first = true;
11508 size_t cnt;
11509 uint64_t val = entry->d_un.d_val;
11511 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
11512 if (val & flags[cnt].bit)
11514 if (! first)
11515 putchar (' ');
11516 fputs (flags[cnt].str, stdout);
11517 first = false;
11518 val ^= flags[cnt].bit;
11521 if (val != 0 || first)
11523 if (! first)
11524 putchar (' ');
11525 print_vma (val, HEX);
11528 break;
11530 default:
11531 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11532 break;
11534 putchar ('\n');
11537 /* VMS vs Unix time offset and factor. */
11539 #define VMS_EPOCH_OFFSET 35067168000000000LL
11540 #define VMS_GRANULARITY_FACTOR 10000000
11541 #ifndef INT64_MIN
11542 #define INT64_MIN (-9223372036854775807LL - 1)
11543 #endif
11545 /* Display a VMS time in a human readable format. */
11547 static void
11548 print_vms_time (int64_t vmstime)
11550 struct tm *tm = NULL;
11551 time_t unxtime;
11553 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
11555 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
11556 unxtime = vmstime;
11557 if (unxtime == vmstime)
11558 tm = gmtime (&unxtime);
11560 if (tm != NULL)
11561 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
11562 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
11563 tm->tm_hour, tm->tm_min, tm->tm_sec);
11566 static void
11567 dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
11569 switch (entry->d_tag)
11571 case DT_IA_64_PLT_RESERVE:
11572 /* First 3 slots reserved. */
11573 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11574 printf (" -- ");
11575 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
11576 break;
11578 case DT_IA_64_VMS_LINKTIME:
11579 print_vms_time (entry->d_un.d_val);
11580 break;
11582 case DT_IA_64_VMS_LNKFLAGS:
11583 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11584 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
11585 printf (" CALL_DEBUG");
11586 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
11587 printf (" NOP0BUFS");
11588 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
11589 printf (" P0IMAGE");
11590 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
11591 printf (" MKTHREADS");
11592 if (entry->d_un.d_val & VMS_LF_UPCALLS)
11593 printf (" UPCALLS");
11594 if (entry->d_un.d_val & VMS_LF_IMGSTA)
11595 printf (" IMGSTA");
11596 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
11597 printf (" INITIALIZE");
11598 if (entry->d_un.d_val & VMS_LF_MAIN)
11599 printf (" MAIN");
11600 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
11601 printf (" EXE_INIT");
11602 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
11603 printf (" TBK_IN_IMG");
11604 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
11605 printf (" DBG_IN_IMG");
11606 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
11607 printf (" TBK_IN_DSF");
11608 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
11609 printf (" DBG_IN_DSF");
11610 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
11611 printf (" SIGNATURES");
11612 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
11613 printf (" REL_SEG_OFF");
11614 break;
11616 default:
11617 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11618 break;
11620 putchar ('\n');
11623 static bool
11624 get_32bit_dynamic_section (Filedata * filedata)
11626 Elf32_External_Dyn * edyn;
11627 Elf32_External_Dyn * ext;
11628 Elf_Internal_Dyn * entry;
11630 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
11631 filedata->dynamic_addr, 1,
11632 filedata->dynamic_size,
11633 _("dynamic section"));
11634 if (!edyn)
11635 return false;
11637 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11638 might not have the luxury of section headers. Look for the DT_NULL
11639 terminator to determine the number of entries. */
11640 for (ext = edyn, filedata->dynamic_nent = 0;
11641 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
11642 ext++)
11644 filedata->dynamic_nent++;
11645 if (BYTE_GET (ext->d_tag) == DT_NULL)
11646 break;
11649 filedata->dynamic_section
11650 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11651 if (filedata->dynamic_section == NULL)
11653 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11654 filedata->dynamic_nent);
11655 free (edyn);
11656 return false;
11659 for (ext = edyn, entry = filedata->dynamic_section;
11660 entry < filedata->dynamic_section + filedata->dynamic_nent;
11661 ext++, entry++)
11663 entry->d_tag = BYTE_GET (ext->d_tag);
11664 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
11667 free (edyn);
11669 return true;
11672 static bool
11673 get_64bit_dynamic_section (Filedata * filedata)
11675 Elf64_External_Dyn * edyn;
11676 Elf64_External_Dyn * ext;
11677 Elf_Internal_Dyn * entry;
11679 /* Read in the data. */
11680 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
11681 filedata->dynamic_addr, 1,
11682 filedata->dynamic_size,
11683 _("dynamic section"));
11684 if (!edyn)
11685 return false;
11687 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11688 might not have the luxury of section headers. Look for the DT_NULL
11689 terminator to determine the number of entries. */
11690 for (ext = edyn, filedata->dynamic_nent = 0;
11691 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
11692 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
11693 ext++)
11695 filedata->dynamic_nent++;
11696 if (BYTE_GET (ext->d_tag) == DT_NULL)
11697 break;
11700 filedata->dynamic_section
11701 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11702 if (filedata->dynamic_section == NULL)
11704 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11705 filedata->dynamic_nent);
11706 free (edyn);
11707 return false;
11710 /* Convert from external to internal formats. */
11711 for (ext = edyn, entry = filedata->dynamic_section;
11712 entry < filedata->dynamic_section + filedata->dynamic_nent;
11713 ext++, entry++)
11715 entry->d_tag = BYTE_GET (ext->d_tag);
11716 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
11719 free (edyn);
11721 return true;
11724 static bool
11725 get_dynamic_section (Filedata *filedata)
11727 if (filedata->dynamic_section)
11728 return true;
11730 if (is_32bit_elf)
11731 return get_32bit_dynamic_section (filedata);
11732 else
11733 return get_64bit_dynamic_section (filedata);
11736 static void
11737 print_dynamic_flags (uint64_t flags)
11739 bool first = true;
11741 while (flags)
11743 uint64_t flag;
11745 flag = flags & - flags;
11746 flags &= ~ flag;
11748 if (first)
11749 first = false;
11750 else
11751 putc (' ', stdout);
11753 switch (flag)
11755 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
11756 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
11757 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
11758 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
11759 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
11760 default: fputs (_("unknown"), stdout); break;
11763 puts ("");
11766 static uint64_t *
11767 get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
11769 unsigned char * e_data;
11770 uint64_t * i_data;
11772 /* If size_t is smaller than uint64_t, eg because you are building
11773 on a 32-bit host, then make sure that when number is cast to
11774 size_t no information is lost. */
11775 if ((size_t) number != number
11776 || ent_size * number / ent_size != number)
11778 error (_("Size overflow prevents reading %" PRIu64
11779 " elements of size %u\n"),
11780 number, ent_size);
11781 return NULL;
11784 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
11785 attempting to allocate memory when the read is bound to fail. */
11786 if (ent_size * number > filedata->file_size)
11788 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
11789 number);
11790 return NULL;
11793 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
11794 if (e_data == NULL)
11796 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
11797 number);
11798 return NULL;
11801 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
11803 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
11804 number * ent_size);
11805 free (e_data);
11806 return NULL;
11809 i_data = (uint64_t *) cmalloc ((size_t) number, sizeof (*i_data));
11810 if (i_data == NULL)
11812 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11813 number);
11814 free (e_data);
11815 return NULL;
11818 while (number--)
11819 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
11821 free (e_data);
11823 return i_data;
11826 static uint64_t
11827 get_num_dynamic_syms (Filedata * filedata)
11829 uint64_t num_of_syms = 0;
11831 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
11832 return num_of_syms;
11834 if (filedata->dynamic_info[DT_HASH])
11836 unsigned char nb[8];
11837 unsigned char nc[8];
11838 unsigned int hash_ent_size = 4;
11840 if ((filedata->file_header.e_machine == EM_ALPHA
11841 || filedata->file_header.e_machine == EM_S390
11842 || filedata->file_header.e_machine == EM_S390_OLD)
11843 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
11844 hash_ent_size = 8;
11846 if (fseek64 (filedata->handle,
11847 (filedata->archive_file_offset
11848 + offset_from_vma (filedata,
11849 filedata->dynamic_info[DT_HASH],
11850 sizeof nb + sizeof nc)),
11851 SEEK_SET))
11853 error (_("Unable to seek to start of dynamic information\n"));
11854 goto no_hash;
11857 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
11859 error (_("Failed to read in number of buckets\n"));
11860 goto no_hash;
11863 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
11865 error (_("Failed to read in number of chains\n"));
11866 goto no_hash;
11869 filedata->nbuckets = byte_get (nb, hash_ent_size);
11870 filedata->nchains = byte_get (nc, hash_ent_size);
11872 if (filedata->nbuckets != 0 && filedata->nchains != 0)
11874 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
11875 hash_ent_size);
11876 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
11877 hash_ent_size);
11879 if (filedata->buckets != NULL && filedata->chains != NULL)
11880 num_of_syms = filedata->nchains;
11882 no_hash:
11883 if (num_of_syms == 0)
11885 free (filedata->buckets);
11886 filedata->buckets = NULL;
11887 free (filedata->chains);
11888 filedata->chains = NULL;
11889 filedata->nbuckets = 0;
11893 if (filedata->dynamic_info_DT_GNU_HASH)
11895 unsigned char nb[16];
11896 uint64_t i, maxchain = 0xffffffff, bitmaskwords;
11897 uint64_t buckets_vma;
11898 uint64_t hn;
11900 if (fseek64 (filedata->handle,
11901 (filedata->archive_file_offset
11902 + offset_from_vma (filedata,
11903 filedata->dynamic_info_DT_GNU_HASH,
11904 sizeof nb)),
11905 SEEK_SET))
11907 error (_("Unable to seek to start of dynamic information\n"));
11908 goto no_gnu_hash;
11911 if (fread (nb, 16, 1, filedata->handle) != 1)
11913 error (_("Failed to read in number of buckets\n"));
11914 goto no_gnu_hash;
11917 filedata->ngnubuckets = byte_get (nb, 4);
11918 filedata->gnusymidx = byte_get (nb + 4, 4);
11919 bitmaskwords = byte_get (nb + 8, 4);
11920 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
11921 if (is_32bit_elf)
11922 buckets_vma += bitmaskwords * 4;
11923 else
11924 buckets_vma += bitmaskwords * 8;
11926 if (fseek64 (filedata->handle,
11927 (filedata->archive_file_offset
11928 + offset_from_vma (filedata, buckets_vma, 4)),
11929 SEEK_SET))
11931 error (_("Unable to seek to start of dynamic information\n"));
11932 goto no_gnu_hash;
11935 filedata->gnubuckets
11936 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
11938 if (filedata->gnubuckets == NULL)
11939 goto no_gnu_hash;
11941 for (i = 0; i < filedata->ngnubuckets; i++)
11942 if (filedata->gnubuckets[i] != 0)
11944 if (filedata->gnubuckets[i] < filedata->gnusymidx)
11945 goto no_gnu_hash;
11947 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11948 maxchain = filedata->gnubuckets[i];
11951 if (maxchain == 0xffffffff)
11952 goto no_gnu_hash;
11954 maxchain -= filedata->gnusymidx;
11956 if (fseek64 (filedata->handle,
11957 (filedata->archive_file_offset
11958 + offset_from_vma (filedata,
11959 buckets_vma + 4 * (filedata->ngnubuckets
11960 + maxchain),
11961 4)),
11962 SEEK_SET))
11964 error (_("Unable to seek to start of dynamic information\n"));
11965 goto no_gnu_hash;
11970 if (fread (nb, 4, 1, filedata->handle) != 1)
11972 error (_("Failed to determine last chain length\n"));
11973 goto no_gnu_hash;
11976 if (maxchain + 1 == 0)
11977 goto no_gnu_hash;
11979 ++maxchain;
11981 while ((byte_get (nb, 4) & 1) == 0);
11983 if (fseek64 (filedata->handle,
11984 (filedata->archive_file_offset
11985 + offset_from_vma (filedata, (buckets_vma
11986 + 4 * filedata->ngnubuckets),
11987 4)),
11988 SEEK_SET))
11990 error (_("Unable to seek to start of dynamic information\n"));
11991 goto no_gnu_hash;
11994 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11995 filedata->ngnuchains = maxchain;
11997 if (filedata->gnuchains == NULL)
11998 goto no_gnu_hash;
12000 if (filedata->dynamic_info_DT_MIPS_XHASH)
12002 if (fseek64 (filedata->handle,
12003 (filedata->archive_file_offset
12004 + offset_from_vma (filedata, (buckets_vma
12005 + 4 * (filedata->ngnubuckets
12006 + maxchain)), 4)),
12007 SEEK_SET))
12009 error (_("Unable to seek to start of dynamic information\n"));
12010 goto no_gnu_hash;
12013 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
12014 if (filedata->mipsxlat == NULL)
12015 goto no_gnu_hash;
12018 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
12019 if (filedata->gnubuckets[hn] != 0)
12021 uint64_t si = filedata->gnubuckets[hn];
12022 uint64_t off = si - filedata->gnusymidx;
12026 if (filedata->dynamic_info_DT_MIPS_XHASH)
12028 if (off < filedata->ngnuchains
12029 && filedata->mipsxlat[off] >= num_of_syms)
12030 num_of_syms = filedata->mipsxlat[off] + 1;
12032 else
12034 if (si >= num_of_syms)
12035 num_of_syms = si + 1;
12037 si++;
12039 while (off < filedata->ngnuchains
12040 && (filedata->gnuchains[off++] & 1) == 0);
12043 if (num_of_syms == 0)
12045 no_gnu_hash:
12046 free (filedata->mipsxlat);
12047 filedata->mipsxlat = NULL;
12048 free (filedata->gnuchains);
12049 filedata->gnuchains = NULL;
12050 free (filedata->gnubuckets);
12051 filedata->gnubuckets = NULL;
12052 filedata->ngnubuckets = 0;
12053 filedata->ngnuchains = 0;
12057 return num_of_syms;
12060 /* Parse and display the contents of the dynamic section. */
12062 static bool
12063 process_dynamic_section (Filedata * filedata)
12065 Elf_Internal_Dyn * entry;
12067 if (filedata->dynamic_size <= 1)
12069 if (do_dynamic)
12071 if (filedata->is_separate)
12072 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
12073 filedata->file_name);
12074 else
12075 printf (_("\nThere is no dynamic section in this file.\n"));
12078 return true;
12081 if (!get_dynamic_section (filedata))
12082 return false;
12084 /* Find the appropriate symbol table. */
12085 if (filedata->dynamic_symbols == NULL || do_histogram)
12087 uint64_t num_of_syms;
12089 for (entry = filedata->dynamic_section;
12090 entry < filedata->dynamic_section + filedata->dynamic_nent;
12091 ++entry)
12092 if (entry->d_tag == DT_SYMTAB)
12093 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
12094 else if (entry->d_tag == DT_SYMENT)
12095 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
12096 else if (entry->d_tag == DT_HASH)
12097 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
12098 else if (entry->d_tag == DT_GNU_HASH)
12099 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
12100 else if ((filedata->file_header.e_machine == EM_MIPS
12101 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
12102 && entry->d_tag == DT_MIPS_XHASH)
12104 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
12105 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
12108 num_of_syms = get_num_dynamic_syms (filedata);
12110 if (num_of_syms != 0
12111 && filedata->dynamic_symbols == NULL
12112 && filedata->dynamic_info[DT_SYMTAB]
12113 && filedata->dynamic_info[DT_SYMENT])
12115 Elf_Internal_Phdr *seg;
12116 uint64_t vma = filedata->dynamic_info[DT_SYMTAB];
12118 if (! get_program_headers (filedata))
12120 error (_("Cannot interpret virtual addresses "
12121 "without program headers.\n"));
12122 return false;
12125 for (seg = filedata->program_headers;
12126 seg < filedata->program_headers + filedata->file_header.e_phnum;
12127 ++seg)
12129 if (seg->p_type != PT_LOAD)
12130 continue;
12132 if (seg->p_offset + seg->p_filesz > filedata->file_size)
12134 /* See PR 21379 for a reproducer. */
12135 error (_("Invalid PT_LOAD entry\n"));
12136 return false;
12139 if (vma >= (seg->p_vaddr & -seg->p_align)
12140 && vma < seg->p_vaddr + seg->p_filesz)
12142 /* Since we do not know how big the symbol table is,
12143 we default to reading in up to the end of PT_LOAD
12144 segment and processing that. This is overkill, I
12145 know, but it should work. */
12146 Elf_Internal_Shdr section;
12147 section.sh_offset = (vma - seg->p_vaddr
12148 + seg->p_offset);
12149 section.sh_size = (num_of_syms
12150 * filedata->dynamic_info[DT_SYMENT]);
12151 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
12153 if (do_checks
12154 && filedata->dynamic_symtab_section != NULL
12155 && ((filedata->dynamic_symtab_section->sh_offset
12156 != section.sh_offset)
12157 || (filedata->dynamic_symtab_section->sh_size
12158 != section.sh_size)
12159 || (filedata->dynamic_symtab_section->sh_entsize
12160 != section.sh_entsize)))
12161 warn (_("\
12162 the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
12164 section.sh_name = filedata->string_table_length;
12165 filedata->dynamic_symbols
12166 = get_elf_symbols (filedata, &section,
12167 &filedata->num_dynamic_syms);
12168 if (filedata->dynamic_symbols == NULL
12169 || filedata->num_dynamic_syms != num_of_syms)
12171 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
12172 return false;
12174 break;
12180 /* Similarly find a string table. */
12181 if (filedata->dynamic_strings == NULL)
12182 for (entry = filedata->dynamic_section;
12183 entry < filedata->dynamic_section + filedata->dynamic_nent;
12184 ++entry)
12186 if (entry->d_tag == DT_STRTAB)
12187 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
12189 if (entry->d_tag == DT_STRSZ)
12190 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
12192 if (filedata->dynamic_info[DT_STRTAB]
12193 && filedata->dynamic_info[DT_STRSZ])
12195 uint64_t offset;
12196 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
12198 offset = offset_from_vma (filedata,
12199 filedata->dynamic_info[DT_STRTAB],
12200 str_tab_len);
12201 if (do_checks
12202 && filedata->dynamic_strtab_section
12203 && ((filedata->dynamic_strtab_section->sh_offset
12204 != (file_ptr) offset)
12205 || (filedata->dynamic_strtab_section->sh_size
12206 != str_tab_len)))
12207 warn (_("\
12208 the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
12210 filedata->dynamic_strings
12211 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
12212 _("dynamic string table"));
12213 if (filedata->dynamic_strings == NULL)
12215 error (_("Corrupt DT_STRTAB dynamic entry\n"));
12216 break;
12219 filedata->dynamic_strings_length = str_tab_len;
12220 break;
12224 /* And find the syminfo section if available. */
12225 if (filedata->dynamic_syminfo == NULL)
12227 uint64_t syminsz = 0;
12229 for (entry = filedata->dynamic_section;
12230 entry < filedata->dynamic_section + filedata->dynamic_nent;
12231 ++entry)
12233 if (entry->d_tag == DT_SYMINENT)
12235 /* Note: these braces are necessary to avoid a syntax
12236 error from the SunOS4 C compiler. */
12237 /* PR binutils/17531: A corrupt file can trigger this test.
12238 So do not use an assert, instead generate an error message. */
12239 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
12240 error (_("Bad value (%d) for SYMINENT entry\n"),
12241 (int) entry->d_un.d_val);
12243 else if (entry->d_tag == DT_SYMINSZ)
12244 syminsz = entry->d_un.d_val;
12245 else if (entry->d_tag == DT_SYMINFO)
12246 filedata->dynamic_syminfo_offset
12247 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
12250 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
12252 Elf_External_Syminfo * extsyminfo;
12253 Elf_External_Syminfo * extsym;
12254 Elf_Internal_Syminfo * syminfo;
12256 /* There is a syminfo section. Read the data. */
12257 extsyminfo = (Elf_External_Syminfo *)
12258 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
12259 1, syminsz, _("symbol information"));
12260 if (!extsyminfo)
12261 return false;
12263 if (filedata->dynamic_syminfo != NULL)
12265 error (_("Multiple dynamic symbol information sections found\n"));
12266 free (filedata->dynamic_syminfo);
12268 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
12269 if (filedata->dynamic_syminfo == NULL)
12271 error (_("Out of memory allocating %" PRIu64
12272 " bytes for dynamic symbol info\n"),
12273 syminsz);
12274 return false;
12277 filedata->dynamic_syminfo_nent
12278 = syminsz / sizeof (Elf_External_Syminfo);
12279 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
12280 syminfo < (filedata->dynamic_syminfo
12281 + filedata->dynamic_syminfo_nent);
12282 ++syminfo, ++extsym)
12284 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
12285 syminfo->si_flags = BYTE_GET (extsym->si_flags);
12288 free (extsyminfo);
12292 if (do_dynamic && filedata->dynamic_addr)
12294 if (filedata->is_separate)
12295 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
12296 "\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
12297 filedata->dynamic_nent),
12298 filedata->file_name,
12299 filedata->dynamic_addr,
12300 filedata->dynamic_nent);
12301 else
12302 printf (ngettext ("\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
12303 "\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
12304 filedata->dynamic_nent),
12305 filedata->dynamic_addr,
12306 filedata->dynamic_nent);
12308 if (do_dynamic)
12309 printf (_(" Tag Type Name/Value\n"));
12311 for (entry = filedata->dynamic_section;
12312 entry < filedata->dynamic_section + filedata->dynamic_nent;
12313 entry++)
12315 if (do_dynamic)
12317 const char * dtype;
12319 putchar (' ');
12320 print_vma (entry->d_tag, FULL_HEX);
12321 dtype = get_dynamic_type (filedata, entry->d_tag);
12322 printf (" (%s)%*s", dtype,
12323 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
12326 switch (entry->d_tag)
12328 case DT_FLAGS:
12329 if (do_dynamic)
12330 print_dynamic_flags (entry->d_un.d_val);
12331 break;
12333 case DT_AUXILIARY:
12334 case DT_FILTER:
12335 case DT_CONFIG:
12336 case DT_DEPAUDIT:
12337 case DT_AUDIT:
12338 if (do_dynamic)
12340 switch (entry->d_tag)
12342 case DT_AUXILIARY:
12343 printf (_("Auxiliary library"));
12344 break;
12346 case DT_FILTER:
12347 printf (_("Filter library"));
12348 break;
12350 case DT_CONFIG:
12351 printf (_("Configuration file"));
12352 break;
12354 case DT_DEPAUDIT:
12355 printf (_("Dependency audit library"));
12356 break;
12358 case DT_AUDIT:
12359 printf (_("Audit library"));
12360 break;
12363 if (valid_dynamic_name (filedata, entry->d_un.d_val))
12364 printf (": [%s]\n",
12365 get_dynamic_name (filedata, entry->d_un.d_val));
12366 else
12368 printf (": ");
12369 print_vma (entry->d_un.d_val, PREFIX_HEX);
12370 putchar ('\n');
12373 break;
12375 case DT_FEATURE:
12376 if (do_dynamic)
12378 printf (_("Flags:"));
12380 if (entry->d_un.d_val == 0)
12381 printf (_(" None\n"));
12382 else
12384 uint64_t val = entry->d_un.d_val;
12386 if (val & DTF_1_PARINIT)
12388 printf (" PARINIT");
12389 val ^= DTF_1_PARINIT;
12391 if (val & DTF_1_CONFEXP)
12393 printf (" CONFEXP");
12394 val ^= DTF_1_CONFEXP;
12396 if (val != 0)
12397 printf (" %" PRIx64, val);
12398 puts ("");
12401 break;
12403 case DT_POSFLAG_1:
12404 if (do_dynamic)
12406 printf (_("Flags:"));
12408 if (entry->d_un.d_val == 0)
12409 printf (_(" None\n"));
12410 else
12412 uint64_t val = entry->d_un.d_val;
12414 if (val & DF_P1_LAZYLOAD)
12416 printf (" LAZYLOAD");
12417 val ^= DF_P1_LAZYLOAD;
12419 if (val & DF_P1_GROUPPERM)
12421 printf (" GROUPPERM");
12422 val ^= DF_P1_GROUPPERM;
12424 if (val != 0)
12425 printf (" %" PRIx64, val);
12426 puts ("");
12429 break;
12431 case DT_FLAGS_1:
12432 if (do_dynamic)
12434 printf (_("Flags:"));
12435 if (entry->d_un.d_val == 0)
12436 printf (_(" None\n"));
12437 else
12439 uint64_t val = entry->d_un.d_val;
12441 if (val & DF_1_NOW)
12443 printf (" NOW");
12444 val ^= DF_1_NOW;
12446 if (val & DF_1_GLOBAL)
12448 printf (" GLOBAL");
12449 val ^= DF_1_GLOBAL;
12451 if (val & DF_1_GROUP)
12453 printf (" GROUP");
12454 val ^= DF_1_GROUP;
12456 if (val & DF_1_NODELETE)
12458 printf (" NODELETE");
12459 val ^= DF_1_NODELETE;
12461 if (val & DF_1_LOADFLTR)
12463 printf (" LOADFLTR");
12464 val ^= DF_1_LOADFLTR;
12466 if (val & DF_1_INITFIRST)
12468 printf (" INITFIRST");
12469 val ^= DF_1_INITFIRST;
12471 if (val & DF_1_NOOPEN)
12473 printf (" NOOPEN");
12474 val ^= DF_1_NOOPEN;
12476 if (val & DF_1_ORIGIN)
12478 printf (" ORIGIN");
12479 val ^= DF_1_ORIGIN;
12481 if (val & DF_1_DIRECT)
12483 printf (" DIRECT");
12484 val ^= DF_1_DIRECT;
12486 if (val & DF_1_TRANS)
12488 printf (" TRANS");
12489 val ^= DF_1_TRANS;
12491 if (val & DF_1_INTERPOSE)
12493 printf (" INTERPOSE");
12494 val ^= DF_1_INTERPOSE;
12496 if (val & DF_1_NODEFLIB)
12498 printf (" NODEFLIB");
12499 val ^= DF_1_NODEFLIB;
12501 if (val & DF_1_NODUMP)
12503 printf (" NODUMP");
12504 val ^= DF_1_NODUMP;
12506 if (val & DF_1_CONFALT)
12508 printf (" CONFALT");
12509 val ^= DF_1_CONFALT;
12511 if (val & DF_1_ENDFILTEE)
12513 printf (" ENDFILTEE");
12514 val ^= DF_1_ENDFILTEE;
12516 if (val & DF_1_DISPRELDNE)
12518 printf (" DISPRELDNE");
12519 val ^= DF_1_DISPRELDNE;
12521 if (val & DF_1_DISPRELPND)
12523 printf (" DISPRELPND");
12524 val ^= DF_1_DISPRELPND;
12526 if (val & DF_1_NODIRECT)
12528 printf (" NODIRECT");
12529 val ^= DF_1_NODIRECT;
12531 if (val & DF_1_IGNMULDEF)
12533 printf (" IGNMULDEF");
12534 val ^= DF_1_IGNMULDEF;
12536 if (val & DF_1_NOKSYMS)
12538 printf (" NOKSYMS");
12539 val ^= DF_1_NOKSYMS;
12541 if (val & DF_1_NOHDR)
12543 printf (" NOHDR");
12544 val ^= DF_1_NOHDR;
12546 if (val & DF_1_EDITED)
12548 printf (" EDITED");
12549 val ^= DF_1_EDITED;
12551 if (val & DF_1_NORELOC)
12553 printf (" NORELOC");
12554 val ^= DF_1_NORELOC;
12556 if (val & DF_1_SYMINTPOSE)
12558 printf (" SYMINTPOSE");
12559 val ^= DF_1_SYMINTPOSE;
12561 if (val & DF_1_GLOBAUDIT)
12563 printf (" GLOBAUDIT");
12564 val ^= DF_1_GLOBAUDIT;
12566 if (val & DF_1_SINGLETON)
12568 printf (" SINGLETON");
12569 val ^= DF_1_SINGLETON;
12571 if (val & DF_1_STUB)
12573 printf (" STUB");
12574 val ^= DF_1_STUB;
12576 if (val & DF_1_PIE)
12578 printf (" PIE");
12579 val ^= DF_1_PIE;
12581 if (val & DF_1_KMOD)
12583 printf (" KMOD");
12584 val ^= DF_1_KMOD;
12586 if (val & DF_1_WEAKFILTER)
12588 printf (" WEAKFILTER");
12589 val ^= DF_1_WEAKFILTER;
12591 if (val & DF_1_NOCOMMON)
12593 printf (" NOCOMMON");
12594 val ^= DF_1_NOCOMMON;
12596 if (val != 0)
12597 printf (" %" PRIx64, val);
12598 puts ("");
12601 break;
12603 case DT_PLTREL:
12604 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
12605 if (do_dynamic)
12606 puts (get_dynamic_type (filedata, entry->d_un.d_val));
12607 break;
12609 case DT_NULL :
12610 case DT_NEEDED :
12611 case DT_PLTGOT :
12612 case DT_HASH :
12613 case DT_STRTAB :
12614 case DT_SYMTAB :
12615 case DT_RELA :
12616 case DT_INIT :
12617 case DT_FINI :
12618 case DT_SONAME :
12619 case DT_RPATH :
12620 case DT_SYMBOLIC:
12621 case DT_REL :
12622 case DT_RELR :
12623 case DT_DEBUG :
12624 case DT_TEXTREL :
12625 case DT_JMPREL :
12626 case DT_RUNPATH :
12627 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
12629 if (do_dynamic)
12631 const char *name;
12633 if (valid_dynamic_name (filedata, entry->d_un.d_val))
12634 name = get_dynamic_name (filedata, entry->d_un.d_val);
12635 else
12636 name = NULL;
12638 if (name)
12640 switch (entry->d_tag)
12642 case DT_NEEDED:
12643 printf (_("Shared library: [%s]"), name);
12645 if (filedata->program_interpreter
12646 && streq (name, filedata->program_interpreter))
12647 printf (_(" program interpreter"));
12648 break;
12650 case DT_SONAME:
12651 printf (_("Library soname: [%s]"), name);
12652 break;
12654 case DT_RPATH:
12655 printf (_("Library rpath: [%s]"), name);
12656 break;
12658 case DT_RUNPATH:
12659 printf (_("Library runpath: [%s]"), name);
12660 break;
12662 default:
12663 print_vma (entry->d_un.d_val, PREFIX_HEX);
12664 break;
12667 else
12668 print_vma (entry->d_un.d_val, PREFIX_HEX);
12670 putchar ('\n');
12672 break;
12674 case DT_PLTRELSZ:
12675 case DT_RELASZ :
12676 case DT_STRSZ :
12677 case DT_RELSZ :
12678 case DT_RELAENT :
12679 case DT_RELRENT :
12680 case DT_RELRSZ :
12681 case DT_SYMENT :
12682 case DT_RELENT :
12683 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
12684 /* Fall through. */
12685 case DT_PLTPADSZ:
12686 case DT_MOVEENT :
12687 case DT_MOVESZ :
12688 case DT_PREINIT_ARRAYSZ:
12689 case DT_INIT_ARRAYSZ:
12690 case DT_FINI_ARRAYSZ:
12691 case DT_GNU_CONFLICTSZ:
12692 case DT_GNU_LIBLISTSZ:
12693 if (do_dynamic)
12695 print_vma (entry->d_un.d_val, UNSIGNED);
12696 printf (_(" (bytes)\n"));
12698 break;
12700 case DT_VERDEFNUM:
12701 case DT_VERNEEDNUM:
12702 case DT_RELACOUNT:
12703 case DT_RELCOUNT:
12704 if (do_dynamic)
12706 print_vma (entry->d_un.d_val, UNSIGNED);
12707 putchar ('\n');
12709 break;
12711 case DT_SYMINSZ:
12712 case DT_SYMINENT:
12713 case DT_SYMINFO:
12714 case DT_USED:
12715 case DT_INIT_ARRAY:
12716 case DT_FINI_ARRAY:
12717 if (do_dynamic)
12719 if (entry->d_tag == DT_USED
12720 && valid_dynamic_name (filedata, entry->d_un.d_val))
12722 const char *name
12723 = get_dynamic_name (filedata, entry->d_un.d_val);
12725 if (*name)
12727 printf (_("Not needed object: [%s]\n"), name);
12728 break;
12732 print_vma (entry->d_un.d_val, PREFIX_HEX);
12733 putchar ('\n');
12735 break;
12737 case DT_BIND_NOW:
12738 /* The value of this entry is ignored. */
12739 if (do_dynamic)
12740 putchar ('\n');
12741 break;
12743 case DT_GNU_PRELINKED:
12744 if (do_dynamic)
12746 struct tm * tmp;
12747 time_t atime = entry->d_un.d_val;
12749 tmp = gmtime (&atime);
12750 /* PR 17533 file: 041-1244816-0.004. */
12751 if (tmp == NULL)
12752 printf (_("<corrupt time val: %" PRIx64),
12753 (uint64_t) atime);
12754 else
12755 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
12756 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12757 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
12760 break;
12762 case DT_GNU_HASH:
12763 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
12764 if (do_dynamic)
12766 print_vma (entry->d_un.d_val, PREFIX_HEX);
12767 putchar ('\n');
12769 break;
12771 case DT_GNU_FLAGS_1:
12772 if (do_dynamic)
12774 printf (_("Flags:"));
12775 if (entry->d_un.d_val == 0)
12776 printf (_(" None\n"));
12777 else
12779 uint64_t val = entry->d_un.d_val;
12781 if (val & DF_GNU_1_UNIQUE)
12783 printf (" UNIQUE");
12784 val ^= DF_GNU_1_UNIQUE;
12786 if (val != 0)
12787 printf (" %" PRIx64, val);
12788 puts ("");
12791 break;
12793 default:
12794 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
12795 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
12796 = entry->d_un.d_val;
12798 if (do_dynamic)
12800 switch (filedata->file_header.e_machine)
12802 case EM_AARCH64:
12803 dynamic_section_aarch64_val (entry);
12804 break;
12805 case EM_MIPS:
12806 case EM_MIPS_RS3_LE:
12807 dynamic_section_mips_val (filedata, entry);
12808 break;
12809 case EM_PARISC:
12810 dynamic_section_parisc_val (entry);
12811 break;
12812 case EM_IA_64:
12813 dynamic_section_ia64_val (entry);
12814 break;
12815 default:
12816 print_vma (entry->d_un.d_val, PREFIX_HEX);
12817 putchar ('\n');
12820 break;
12824 return true;
12827 static char *
12828 get_ver_flags (unsigned int flags)
12830 static char buff[128];
12832 buff[0] = 0;
12834 if (flags == 0)
12835 return _("none");
12837 if (flags & VER_FLG_BASE)
12838 strcat (buff, "BASE");
12840 if (flags & VER_FLG_WEAK)
12842 if (flags & VER_FLG_BASE)
12843 strcat (buff, " | ");
12845 strcat (buff, "WEAK");
12848 if (flags & VER_FLG_INFO)
12850 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
12851 strcat (buff, " | ");
12853 strcat (buff, "INFO");
12856 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12858 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12859 strcat (buff, " | ");
12861 strcat (buff, _("<unknown>"));
12864 return buff;
12867 /* Display the contents of the version sections. */
12869 static bool
12870 process_version_sections (Filedata * filedata)
12872 Elf_Internal_Shdr * section;
12873 unsigned i;
12874 bool found = false;
12876 if (! do_version)
12877 return true;
12879 for (i = 0, section = filedata->section_headers;
12880 i < filedata->file_header.e_shnum;
12881 i++, section++)
12883 switch (section->sh_type)
12885 case SHT_GNU_verdef:
12887 Elf_External_Verdef * edefs;
12888 size_t idx;
12889 size_t cnt;
12890 char * endbuf;
12892 found = true;
12894 if (filedata->is_separate)
12895 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12896 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12897 section->sh_info),
12898 filedata->file_name,
12899 printable_section_name (filedata, section),
12900 section->sh_info);
12901 else
12902 printf (ngettext ("\nVersion definition section '%s' "
12903 "contains %u entry:\n",
12904 "\nVersion definition section '%s' "
12905 "contains %u entries:\n",
12906 section->sh_info),
12907 printable_section_name (filedata, section),
12908 section->sh_info);
12910 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
12911 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12912 section->sh_offset, section->sh_link,
12913 printable_section_name_from_index (filedata, section->sh_link, NULL));
12915 edefs = (Elf_External_Verdef *)
12916 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
12917 _("version definition section"));
12918 if (!edefs)
12919 break;
12920 endbuf = (char *) edefs + section->sh_size;
12922 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12924 char * vstart;
12925 Elf_External_Verdef * edef;
12926 Elf_Internal_Verdef ent;
12927 Elf_External_Verdaux * eaux;
12928 Elf_Internal_Verdaux aux;
12929 size_t isum;
12930 int j;
12932 vstart = ((char *) edefs) + idx;
12933 if (vstart + sizeof (*edef) > endbuf)
12934 break;
12936 edef = (Elf_External_Verdef *) vstart;
12938 ent.vd_version = BYTE_GET (edef->vd_version);
12939 ent.vd_flags = BYTE_GET (edef->vd_flags);
12940 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12941 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12942 ent.vd_hash = BYTE_GET (edef->vd_hash);
12943 ent.vd_aux = BYTE_GET (edef->vd_aux);
12944 ent.vd_next = BYTE_GET (edef->vd_next);
12946 printf (_(" %#06zx: Rev: %d Flags: %s"),
12947 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12949 printf (_(" Index: %d Cnt: %d "),
12950 ent.vd_ndx, ent.vd_cnt);
12952 /* Check for overflow. */
12953 if (ent.vd_aux > (size_t) (endbuf - vstart))
12954 break;
12956 vstart += ent.vd_aux;
12958 if (vstart + sizeof (*eaux) > endbuf)
12959 break;
12960 eaux = (Elf_External_Verdaux *) vstart;
12962 aux.vda_name = BYTE_GET (eaux->vda_name);
12963 aux.vda_next = BYTE_GET (eaux->vda_next);
12965 if (valid_dynamic_name (filedata, aux.vda_name))
12966 printf (_("Name: %s\n"),
12967 get_dynamic_name (filedata, aux.vda_name));
12968 else
12969 printf (_("Name index: %ld\n"), aux.vda_name);
12971 isum = idx + ent.vd_aux;
12973 for (j = 1; j < ent.vd_cnt; j++)
12975 if (aux.vda_next < sizeof (*eaux)
12976 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12978 warn (_("Invalid vda_next field of %lx\n"),
12979 aux.vda_next);
12980 j = ent.vd_cnt;
12981 break;
12983 /* Check for overflow. */
12984 if (aux.vda_next > (size_t) (endbuf - vstart))
12985 break;
12987 isum += aux.vda_next;
12988 vstart += aux.vda_next;
12990 if (vstart + sizeof (*eaux) > endbuf)
12991 break;
12992 eaux = (Elf_External_Verdaux *) vstart;
12994 aux.vda_name = BYTE_GET (eaux->vda_name);
12995 aux.vda_next = BYTE_GET (eaux->vda_next);
12997 if (valid_dynamic_name (filedata, aux.vda_name))
12998 printf (_(" %#06zx: Parent %d: %s\n"),
12999 isum, j,
13000 get_dynamic_name (filedata, aux.vda_name));
13001 else
13002 printf (_(" %#06zx: Parent %d, name index: %ld\n"),
13003 isum, j, aux.vda_name);
13006 if (j < ent.vd_cnt)
13007 printf (_(" Version def aux past end of section\n"));
13009 /* PR 17531:
13010 file: id:000001,src:000172+005151,op:splice,rep:2. */
13011 if (ent.vd_next < sizeof (*edef)
13012 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
13014 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
13015 cnt = section->sh_info;
13016 break;
13018 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
13019 break;
13021 idx += ent.vd_next;
13024 if (cnt < section->sh_info)
13025 printf (_(" Version definition past end of section\n"));
13027 free (edefs);
13029 break;
13031 case SHT_GNU_verneed:
13033 Elf_External_Verneed * eneed;
13034 size_t idx;
13035 size_t cnt;
13036 char * endbuf;
13038 found = true;
13040 if (filedata->is_separate)
13041 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
13042 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
13043 section->sh_info),
13044 filedata->file_name,
13045 printable_section_name (filedata, section),
13046 section->sh_info);
13047 else
13048 printf (ngettext ("\nVersion needs section '%s' "
13049 "contains %u entry:\n",
13050 "\nVersion needs section '%s' "
13051 "contains %u entries:\n",
13052 section->sh_info),
13053 printable_section_name (filedata, section),
13054 section->sh_info);
13056 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
13057 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
13058 section->sh_offset, section->sh_link,
13059 printable_section_name_from_index (filedata, section->sh_link, NULL));
13061 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
13062 section->sh_offset, 1,
13063 section->sh_size,
13064 _("Version Needs section"));
13065 if (!eneed)
13066 break;
13067 endbuf = (char *) eneed + section->sh_size;
13069 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
13071 Elf_External_Verneed * entry;
13072 Elf_Internal_Verneed ent;
13073 size_t isum;
13074 int j;
13075 char * vstart;
13077 vstart = ((char *) eneed) + idx;
13078 if (vstart + sizeof (*entry) > endbuf)
13079 break;
13081 entry = (Elf_External_Verneed *) vstart;
13083 ent.vn_version = BYTE_GET (entry->vn_version);
13084 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
13085 ent.vn_file = BYTE_GET (entry->vn_file);
13086 ent.vn_aux = BYTE_GET (entry->vn_aux);
13087 ent.vn_next = BYTE_GET (entry->vn_next);
13089 printf (_(" %#06zx: Version: %d"), idx, ent.vn_version);
13091 if (valid_dynamic_name (filedata, ent.vn_file))
13092 printf (_(" File: %s"),
13093 get_dynamic_name (filedata, ent.vn_file));
13094 else
13095 printf (_(" File: %lx"), ent.vn_file);
13097 printf (_(" Cnt: %d\n"), ent.vn_cnt);
13099 /* Check for overflow. */
13100 if (ent.vn_aux > (size_t) (endbuf - vstart))
13101 break;
13102 vstart += ent.vn_aux;
13104 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
13106 Elf_External_Vernaux * eaux;
13107 Elf_Internal_Vernaux aux;
13109 if (vstart + sizeof (*eaux) > endbuf)
13110 break;
13111 eaux = (Elf_External_Vernaux *) vstart;
13113 aux.vna_hash = BYTE_GET (eaux->vna_hash);
13114 aux.vna_flags = BYTE_GET (eaux->vna_flags);
13115 aux.vna_other = BYTE_GET (eaux->vna_other);
13116 aux.vna_name = BYTE_GET (eaux->vna_name);
13117 aux.vna_next = BYTE_GET (eaux->vna_next);
13119 if (valid_dynamic_name (filedata, aux.vna_name))
13120 printf (_(" %#06zx: Name: %s"),
13121 isum, get_dynamic_name (filedata, aux.vna_name));
13122 else
13123 printf (_(" %#06zx: Name index: %lx"),
13124 isum, aux.vna_name);
13126 printf (_(" Flags: %s Version: %d\n"),
13127 get_ver_flags (aux.vna_flags), aux.vna_other);
13129 if (aux.vna_next < sizeof (*eaux)
13130 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
13132 warn (_("Invalid vna_next field of %lx\n"),
13133 aux.vna_next);
13134 j = ent.vn_cnt;
13135 break;
13137 /* Check for overflow. */
13138 if (aux.vna_next > (size_t) (endbuf - vstart))
13139 break;
13140 isum += aux.vna_next;
13141 vstart += aux.vna_next;
13144 if (j < ent.vn_cnt)
13145 warn (_("Missing Version Needs auxiliary information\n"));
13147 if (ent.vn_next < sizeof (*entry)
13148 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
13150 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
13151 cnt = section->sh_info;
13152 break;
13154 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
13155 break;
13156 idx += ent.vn_next;
13159 if (cnt < section->sh_info)
13160 warn (_("Missing Version Needs information\n"));
13162 free (eneed);
13164 break;
13166 case SHT_GNU_versym:
13168 Elf_Internal_Shdr * link_section;
13169 uint64_t total;
13170 unsigned int cnt;
13171 unsigned char * edata;
13172 unsigned short * data;
13173 char * strtab;
13174 Elf_Internal_Sym * symbols;
13175 Elf_Internal_Shdr * string_sec;
13176 uint64_t num_syms;
13177 uint64_t off;
13179 if (section->sh_link >= filedata->file_header.e_shnum)
13180 break;
13182 link_section = filedata->section_headers + section->sh_link;
13183 total = section->sh_size / sizeof (Elf_External_Versym);
13185 if (link_section->sh_link >= filedata->file_header.e_shnum)
13186 break;
13188 found = true;
13190 symbols = get_elf_symbols (filedata, link_section, & num_syms);
13191 if (symbols == NULL)
13192 break;
13194 string_sec = filedata->section_headers + link_section->sh_link;
13196 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
13197 string_sec->sh_size,
13198 _("version string table"));
13199 if (!strtab)
13201 free (symbols);
13202 break;
13205 if (filedata->is_separate)
13206 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entry:\n",
13207 "\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entries:\n",
13208 total),
13209 filedata->file_name,
13210 printable_section_name (filedata, section),
13211 total);
13212 else
13213 printf (ngettext ("\nVersion symbols section '%s' "
13214 "contains %" PRIu64 " entry:\n",
13215 "\nVersion symbols section '%s' "
13216 "contains %" PRIu64 " entries:\n",
13217 total),
13218 printable_section_name (filedata, section),
13219 total);
13221 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
13222 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
13223 section->sh_offset, section->sh_link,
13224 printable_section_name (filedata, link_section));
13226 off = offset_from_vma (filedata,
13227 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
13228 total * sizeof (short));
13229 edata = (unsigned char *) get_data (NULL, filedata, off,
13230 sizeof (short), total,
13231 _("version symbol data"));
13232 if (!edata)
13234 free (strtab);
13235 free (symbols);
13236 break;
13239 data = (short unsigned int *) cmalloc (total, sizeof (short));
13241 for (cnt = total; cnt --;)
13242 data[cnt] = byte_get (edata + cnt * sizeof (short),
13243 sizeof (short));
13245 free (edata);
13247 for (cnt = 0; cnt < total; cnt += 4)
13249 int j, nn;
13250 char *name;
13251 char *invalid = _("*invalid*");
13253 printf (" %03x:", cnt);
13255 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
13256 switch (data[cnt + j])
13258 case 0:
13259 fputs (_(" 0 (*local*) "), stdout);
13260 break;
13262 case 1:
13263 fputs (_(" 1 (*global*) "), stdout);
13264 break;
13266 default:
13267 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
13268 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
13270 /* If this index value is greater than the size of the symbols
13271 array, break to avoid an out-of-bounds read. */
13272 if (cnt + j >= num_syms)
13274 warn (_("invalid index into symbol array\n"));
13275 break;
13278 name = NULL;
13279 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
13281 Elf_Internal_Verneed ivn;
13282 uint64_t offset;
13284 offset = offset_from_vma
13285 (filedata,
13286 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
13287 sizeof (Elf_External_Verneed));
13291 Elf_Internal_Vernaux ivna;
13292 Elf_External_Verneed evn;
13293 Elf_External_Vernaux evna;
13294 uint64_t a_off;
13296 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
13297 _("version need")) == NULL)
13298 break;
13300 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13301 ivn.vn_next = BYTE_GET (evn.vn_next);
13303 a_off = offset + ivn.vn_aux;
13307 if (get_data (&evna, filedata, a_off, sizeof (evna),
13308 1, _("version need aux (2)")) == NULL)
13310 ivna.vna_next = 0;
13311 ivna.vna_other = 0;
13313 else
13315 ivna.vna_next = BYTE_GET (evna.vna_next);
13316 ivna.vna_other = BYTE_GET (evna.vna_other);
13319 a_off += ivna.vna_next;
13321 while (ivna.vna_other != data[cnt + j]
13322 && ivna.vna_next != 0);
13324 if (ivna.vna_other == data[cnt + j])
13326 ivna.vna_name = BYTE_GET (evna.vna_name);
13328 if (ivna.vna_name >= string_sec->sh_size)
13329 name = invalid;
13330 else
13331 name = strtab + ivna.vna_name;
13332 break;
13335 offset += ivn.vn_next;
13337 while (ivn.vn_next);
13340 if (data[cnt + j] != 0x8001
13341 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
13343 Elf_Internal_Verdef ivd;
13344 Elf_External_Verdef evd;
13345 uint64_t offset;
13347 offset = offset_from_vma
13348 (filedata,
13349 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
13350 sizeof evd);
13354 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
13355 _("version def")) == NULL)
13357 ivd.vd_next = 0;
13358 /* PR 17531: file: 046-1082287-0.004. */
13359 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
13360 break;
13362 else
13364 ivd.vd_next = BYTE_GET (evd.vd_next);
13365 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13368 offset += ivd.vd_next;
13370 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
13371 && ivd.vd_next != 0);
13373 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
13375 Elf_External_Verdaux evda;
13376 Elf_Internal_Verdaux ivda;
13378 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13380 if (get_data (&evda, filedata,
13381 offset - ivd.vd_next + ivd.vd_aux,
13382 sizeof (evda), 1,
13383 _("version def aux")) == NULL)
13384 break;
13386 ivda.vda_name = BYTE_GET (evda.vda_name);
13388 if (ivda.vda_name >= string_sec->sh_size)
13389 name = invalid;
13390 else if (name != NULL && name != invalid)
13391 name = _("*both*");
13392 else
13393 name = strtab + ivda.vda_name;
13396 if (name != NULL)
13397 nn += printf ("(%s%-*s",
13398 name,
13399 12 - (int) strlen (name),
13400 ")");
13402 if (nn < 18)
13403 printf ("%*c", 18 - nn, ' ');
13406 putchar ('\n');
13409 free (data);
13410 free (strtab);
13411 free (symbols);
13413 break;
13415 default:
13416 break;
13420 if (! found)
13422 if (filedata->is_separate)
13423 printf (_("\nNo version information found in linked file '%s'.\n"),
13424 filedata->file_name);
13425 else
13426 printf (_("\nNo version information found in this file.\n"));
13429 return true;
13432 static const char *
13433 get_symbol_binding (Filedata * filedata, unsigned int binding)
13435 static char buff[64];
13437 switch (binding)
13439 case STB_LOCAL: return "LOCAL";
13440 case STB_GLOBAL: return "GLOBAL";
13441 case STB_WEAK: return "WEAK";
13442 default:
13443 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
13444 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
13445 binding);
13446 else if (binding >= STB_LOOS && binding <= STB_HIOS)
13448 if (binding == STB_GNU_UNIQUE
13449 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
13450 return "UNIQUE";
13451 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
13453 else
13454 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
13455 return buff;
13459 static const char *
13460 get_symbol_type (Filedata * filedata, unsigned int type)
13462 static char buff[64];
13464 switch (type)
13466 case STT_NOTYPE: return "NOTYPE";
13467 case STT_OBJECT: return "OBJECT";
13468 case STT_FUNC: return "FUNC";
13469 case STT_SECTION: return "SECTION";
13470 case STT_FILE: return "FILE";
13471 case STT_COMMON: return "COMMON";
13472 case STT_TLS: return "TLS";
13473 case STT_RELC: return "RELC";
13474 case STT_SRELC: return "SRELC";
13475 default:
13476 if (type >= STT_LOPROC && type <= STT_HIPROC)
13478 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
13479 return "THUMB_FUNC";
13481 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
13482 return "REGISTER";
13484 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
13485 return "PARISC_MILLI";
13487 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
13489 else if (type >= STT_LOOS && type <= STT_HIOS)
13491 if (filedata->file_header.e_machine == EM_PARISC)
13493 if (type == STT_HP_OPAQUE)
13494 return "HP_OPAQUE";
13495 if (type == STT_HP_STUB)
13496 return "HP_STUB";
13499 if (type == STT_GNU_IFUNC
13500 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
13501 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
13502 return "IFUNC";
13504 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
13506 else
13507 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
13508 return buff;
13512 static const char *
13513 get_symbol_visibility (unsigned int visibility)
13515 switch (visibility)
13517 case STV_DEFAULT: return "DEFAULT";
13518 case STV_INTERNAL: return "INTERNAL";
13519 case STV_HIDDEN: return "HIDDEN";
13520 case STV_PROTECTED: return "PROTECTED";
13521 default:
13522 error (_("Unrecognized visibility value: %u\n"), visibility);
13523 return _("<unknown>");
13527 static const char *
13528 get_alpha_symbol_other (unsigned int other)
13530 switch (other)
13532 case STO_ALPHA_NOPV: return "NOPV";
13533 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
13534 default:
13535 error (_("Unrecognized alpha specific other value: %u\n"), other);
13536 return _("<unknown>");
13540 static const char *
13541 get_solaris_symbol_visibility (unsigned int visibility)
13543 switch (visibility)
13545 case 4: return "EXPORTED";
13546 case 5: return "SINGLETON";
13547 case 6: return "ELIMINATE";
13548 default: return get_symbol_visibility (visibility);
13552 static const char *
13553 get_aarch64_symbol_other (unsigned int other)
13555 static char buf[32];
13557 if (other & STO_AARCH64_VARIANT_PCS)
13559 other &= ~STO_AARCH64_VARIANT_PCS;
13560 if (other == 0)
13561 return "VARIANT_PCS";
13562 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
13563 return buf;
13565 return NULL;
13568 static const char *
13569 get_mips_symbol_other (unsigned int other)
13571 switch (other)
13573 case STO_OPTIONAL: return "OPTIONAL";
13574 case STO_MIPS_PLT: return "MIPS PLT";
13575 case STO_MIPS_PIC: return "MIPS PIC";
13576 case STO_MICROMIPS: return "MICROMIPS";
13577 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
13578 case STO_MIPS16: return "MIPS16";
13579 default: return NULL;
13583 static const char *
13584 get_ia64_symbol_other (Filedata * filedata, unsigned int other)
13586 if (is_ia64_vms (filedata))
13588 static char res[32];
13590 res[0] = 0;
13592 /* Function types is for images and .STB files only. */
13593 switch (filedata->file_header.e_type)
13595 case ET_DYN:
13596 case ET_EXEC:
13597 switch (VMS_ST_FUNC_TYPE (other))
13599 case VMS_SFT_CODE_ADDR:
13600 strcat (res, " CA");
13601 break;
13602 case VMS_SFT_SYMV_IDX:
13603 strcat (res, " VEC");
13604 break;
13605 case VMS_SFT_FD:
13606 strcat (res, " FD");
13607 break;
13608 case VMS_SFT_RESERVE:
13609 strcat (res, " RSV");
13610 break;
13611 default:
13612 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
13613 VMS_ST_FUNC_TYPE (other));
13614 strcat (res, " <unknown>");
13615 break;
13617 break;
13618 default:
13619 break;
13621 switch (VMS_ST_LINKAGE (other))
13623 case VMS_STL_IGNORE:
13624 strcat (res, " IGN");
13625 break;
13626 case VMS_STL_RESERVE:
13627 strcat (res, " RSV");
13628 break;
13629 case VMS_STL_STD:
13630 strcat (res, " STD");
13631 break;
13632 case VMS_STL_LNK:
13633 strcat (res, " LNK");
13634 break;
13635 default:
13636 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
13637 VMS_ST_LINKAGE (other));
13638 strcat (res, " <unknown>");
13639 break;
13642 if (res[0] != 0)
13643 return res + 1;
13644 else
13645 return res;
13647 return NULL;
13650 static const char *
13651 get_ppc64_symbol_other (unsigned int other)
13653 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
13654 return NULL;
13656 other >>= STO_PPC64_LOCAL_BIT;
13657 if (other <= 6)
13659 static char buf[64];
13660 if (other >= 2)
13661 other = ppc64_decode_local_entry (other);
13662 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
13663 return buf;
13665 return NULL;
13668 static const char *
13669 get_riscv_symbol_other (unsigned int other)
13671 static char buf[32];
13672 buf[0] = 0;
13674 if (other & STO_RISCV_VARIANT_CC)
13676 strcat (buf, _(" VARIANT_CC"));
13677 other &= ~STO_RISCV_VARIANT_CC;
13680 if (other != 0)
13681 snprintf (buf, sizeof buf, " %x", other);
13684 if (buf[0] != 0)
13685 return buf + 1;
13686 else
13687 return buf;
13690 static const char *
13691 get_symbol_other (Filedata * filedata, unsigned int other)
13693 const char * result = NULL;
13694 static char buff [64];
13696 if (other == 0)
13697 return "";
13699 switch (filedata->file_header.e_machine)
13701 case EM_ALPHA:
13702 result = get_alpha_symbol_other (other);
13703 break;
13704 case EM_AARCH64:
13705 result = get_aarch64_symbol_other (other);
13706 break;
13707 case EM_MIPS:
13708 result = get_mips_symbol_other (other);
13709 break;
13710 case EM_IA_64:
13711 result = get_ia64_symbol_other (filedata, other);
13712 break;
13713 case EM_PPC64:
13714 result = get_ppc64_symbol_other (other);
13715 break;
13716 case EM_RISCV:
13717 result = get_riscv_symbol_other (other);
13718 break;
13719 default:
13720 result = NULL;
13721 break;
13724 if (result)
13725 return result;
13727 snprintf (buff, sizeof buff, _("<other>: %x"), other);
13728 return buff;
13731 static const char *
13732 get_symbol_version_string (Filedata *filedata,
13733 bool is_dynsym,
13734 const char *strtab,
13735 size_t strtab_size,
13736 unsigned int si,
13737 Elf_Internal_Sym *psym,
13738 enum versioned_symbol_info *sym_info,
13739 unsigned short *vna_other)
13741 unsigned char data[2];
13742 unsigned short vers_data;
13743 uint64_t offset;
13744 unsigned short max_vd_ndx;
13746 if (!is_dynsym
13747 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
13748 return NULL;
13750 offset = offset_from_vma (filedata,
13751 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
13752 sizeof data + si * sizeof (vers_data));
13754 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
13755 sizeof (data), 1, _("version data")) == NULL)
13756 return NULL;
13758 vers_data = byte_get (data, 2);
13760 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
13761 return NULL;
13763 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
13764 max_vd_ndx = 0;
13766 /* Usually we'd only see verdef for defined symbols, and verneed for
13767 undefined symbols. However, symbols defined by the linker in
13768 .dynbss for variables copied from a shared library in order to
13769 avoid text relocations are defined yet have verneed. We could
13770 use a heuristic to detect the special case, for example, check
13771 for verneed first on symbols defined in SHT_NOBITS sections, but
13772 it is simpler and more reliable to just look for both verdef and
13773 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
13775 if (psym->st_shndx != SHN_UNDEF
13776 && vers_data != 0x8001
13777 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
13779 Elf_Internal_Verdef ivd;
13780 Elf_Internal_Verdaux ivda;
13781 Elf_External_Verdaux evda;
13782 uint64_t off;
13784 off = offset_from_vma (filedata,
13785 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
13786 sizeof (Elf_External_Verdef));
13790 Elf_External_Verdef evd;
13792 if (get_data (&evd, filedata, off, sizeof (evd), 1,
13793 _("version def")) == NULL)
13795 ivd.vd_ndx = 0;
13796 ivd.vd_aux = 0;
13797 ivd.vd_next = 0;
13798 ivd.vd_flags = 0;
13800 else
13802 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13803 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13804 ivd.vd_next = BYTE_GET (evd.vd_next);
13805 ivd.vd_flags = BYTE_GET (evd.vd_flags);
13808 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
13809 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
13811 off += ivd.vd_next;
13813 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
13815 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
13817 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
13818 return NULL;
13820 off -= ivd.vd_next;
13821 off += ivd.vd_aux;
13823 if (get_data (&evda, filedata, off, sizeof (evda), 1,
13824 _("version def aux")) != NULL)
13826 ivda.vda_name = BYTE_GET (evda.vda_name);
13828 if (psym->st_name != ivda.vda_name)
13829 return (ivda.vda_name < strtab_size
13830 ? strtab + ivda.vda_name : _("<corrupt>"));
13835 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
13837 Elf_External_Verneed evn;
13838 Elf_Internal_Verneed ivn;
13839 Elf_Internal_Vernaux ivna;
13841 offset = offset_from_vma (filedata,
13842 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
13843 sizeof evn);
13846 uint64_t vna_off;
13848 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
13849 _("version need")) == NULL)
13851 ivna.vna_next = 0;
13852 ivna.vna_other = 0;
13853 ivna.vna_name = 0;
13854 break;
13857 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13858 ivn.vn_next = BYTE_GET (evn.vn_next);
13860 vna_off = offset + ivn.vn_aux;
13864 Elf_External_Vernaux evna;
13866 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
13867 _("version need aux (3)")) == NULL)
13869 ivna.vna_next = 0;
13870 ivna.vna_other = 0;
13871 ivna.vna_name = 0;
13873 else
13875 ivna.vna_other = BYTE_GET (evna.vna_other);
13876 ivna.vna_next = BYTE_GET (evna.vna_next);
13877 ivna.vna_name = BYTE_GET (evna.vna_name);
13880 vna_off += ivna.vna_next;
13882 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
13884 if (ivna.vna_other == vers_data)
13885 break;
13887 offset += ivn.vn_next;
13889 while (ivn.vn_next != 0);
13891 if (ivna.vna_other == vers_data)
13893 *sym_info = symbol_undefined;
13894 *vna_other = ivna.vna_other;
13895 return (ivna.vna_name < strtab_size
13896 ? strtab + ivna.vna_name : _("<corrupt>"));
13898 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
13899 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
13900 return _("<corrupt>");
13902 return NULL;
13905 /* Display a symbol size on stdout. Format is based on --sym-base setting. */
13907 static unsigned int
13908 print_symbol_size (uint64_t vma, int base)
13910 switch (base)
13912 case 8:
13913 return print_vma (vma, OCTAL_5);
13915 case 10:
13916 return print_vma (vma, UNSIGNED_5);
13918 case 16:
13919 return print_vma (vma, PREFIX_HEX_5);
13921 case 0:
13922 default:
13923 return print_vma (vma, DEC_5);
13927 /* Print information on a single symbol. */
13929 static void
13930 print_symbol (Filedata * filedata,
13931 uint64_t symbol_index,
13932 Elf_Internal_Sym * symtab,
13933 Elf_Internal_Shdr * section,
13934 char * strtab,
13935 size_t strtab_size)
13937 const char *version_string;
13938 enum versioned_symbol_info sym_info;
13939 unsigned short vna_other;
13940 const char * sstr;
13941 Elf_Internal_Sym *psym = symtab + symbol_index;
13943 /* FIXME: We should have a table of field widths,
13944 rather than using hard coded constants. */
13945 printf ("%6" PRId64 ": ", symbol_index);
13946 print_vma (psym->st_value, LONG_HEX);
13947 putchar (' ');
13948 print_symbol_size (psym->st_size, sym_base);
13949 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13950 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13951 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13952 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13953 else
13955 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
13957 printf (" %-7s", get_symbol_visibility (vis));
13959 /* Check to see if any other bits in the st_other field are set.
13960 FIXME: Displaying this information here disrupts the layout
13961 of the table being generated. */
13962 if (psym->st_other ^ vis)
13963 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
13966 bool is_special;
13968 sstr = printable_section_name_from_index (filedata, psym->st_shndx, & is_special);
13970 /* Print the symbol's section index. If the index is special
13971 then print the index's name rather than its number. */
13972 if (is_special)
13974 int printed;
13976 /* Special case: If there are no section headers, and the printable
13977 name is "<section 0x...." then just display the section number
13978 as a decimal. This happens when objcopy --strip -section-headers
13979 is used. */
13980 if (filedata->file_header.e_shnum == 0 && startswith (sstr, "<section"))
13981 printed = printf (" %4d ", psym->st_shndx);
13982 else
13983 printed = printf (" %4s ", sstr);
13985 if (extra_sym_info && printed < 16)
13986 printf ("%*s", 16 - printed, "");
13988 else
13990 printf (" %4u ", psym->st_shndx);
13992 if (extra_sym_info)
13994 /* Display the section name referenced by the section index. */
13995 int printed = printf ("(%s) ", sstr);
13996 if (printed < 10)
13997 printf ("%*s", 10 - printed, "");
14001 /* Get the symbol's name. For section symbols without a
14002 specific name use the (already computed) section name. */
14003 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
14004 && section_index_real (filedata, psym->st_shndx)
14005 && psym->st_name == 0)
14009 else
14011 bool is_valid;
14013 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
14014 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
14017 version_string
14018 = get_symbol_version_string (filedata,
14019 (section == NULL
14020 || section->sh_type == SHT_DYNSYM),
14021 strtab, strtab_size, symbol_index,
14022 psym, &sym_info, &vna_other);
14024 int len_avail = 21;
14025 if (! do_wide && version_string != NULL)
14027 char buffer[16];
14029 len_avail -= 1 + strlen (version_string);
14031 if (sym_info == symbol_undefined)
14032 len_avail -= sprintf (buffer," (%d)", vna_other);
14033 else if (sym_info != symbol_hidden)
14034 len_avail -= 1;
14037 print_symbol_name (len_avail, sstr);
14039 if (version_string)
14041 if (sym_info == symbol_undefined)
14042 printf ("@%s (%d)", version_string, vna_other);
14043 else
14044 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
14045 version_string);
14048 putchar ('\n');
14050 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
14051 && section != NULL
14052 && symbol_index >= section->sh_info
14053 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
14054 && filedata->file_header.e_machine != EM_MIPS
14055 /* Solaris binaries have been found to violate this requirement as
14056 well. Not sure if this is a bug or an ABI requirement. */
14057 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
14058 warn (_("local symbol %" PRIu64 " found at index >= %s's sh_info value of %u\n"),
14059 symbol_index, printable_section_name (filedata, section), section->sh_info);
14062 static const char *
14063 get_lto_kind (unsigned int kind)
14065 switch (kind)
14067 case 0: return "DEF";
14068 case 1: return "WEAKDEF";
14069 case 2: return "UNDEF";
14070 case 3: return "WEAKUNDEF";
14071 case 4: return "COMMON";
14072 default:
14073 break;
14076 static char buffer[30];
14077 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
14078 sprintf (buffer, "<unknown: %u>", kind);
14079 return buffer;
14082 static const char *
14083 get_lto_visibility (unsigned int visibility)
14085 switch (visibility)
14087 case 0: return "DEFAULT";
14088 case 1: return "PROTECTED";
14089 case 2: return "INTERNAL";
14090 case 3: return "HIDDEN";
14091 default:
14092 break;
14095 static char buffer[30];
14096 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
14097 sprintf (buffer, "<unknown: %u>", visibility);
14098 return buffer;
14101 static const char *
14102 get_lto_sym_type (unsigned int sym_type)
14104 switch (sym_type)
14106 case 0: return "UNKNOWN";
14107 case 1: return "FUNCTION";
14108 case 2: return "VARIABLE";
14109 default:
14110 break;
14113 static char buffer[30];
14114 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
14115 sprintf (buffer, "<unknown: %u>", sym_type);
14116 return buffer;
14119 /* Display an LTO format symbol table.
14120 FIXME: The format of LTO symbol tables is not formalized.
14121 So this code could need changing in the future. */
14123 static bool
14124 display_lto_symtab (Filedata * filedata,
14125 Elf_Internal_Shdr * section)
14127 if (section->sh_size == 0)
14129 if (filedata->is_separate)
14130 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
14131 printable_section_name (filedata, section),
14132 filedata->file_name);
14133 else
14134 printf (_("\nLTO Symbol table '%s' is empty!\n"),
14135 printable_section_name (filedata, section));
14137 return true;
14140 if (section->sh_size > filedata->file_size)
14142 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
14143 printable_section_name (filedata, section),
14144 section->sh_size);
14145 return false;
14148 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
14149 section->sh_size, 1, _("LTO symbols"));
14150 if (alloced_data == NULL)
14151 return false;
14153 /* Look for extended data for the symbol table. */
14154 Elf_Internal_Shdr * ext = NULL;
14155 void * ext_data_orig = NULL;
14156 char * ext_data = NULL;
14157 char * ext_data_end = NULL;
14158 char * ext_name = NULL;
14160 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
14161 (section_name (filedata, section)
14162 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
14163 && ext_name != NULL /* Paranoia. */
14164 && (ext = find_section (filedata, ext_name)) != NULL)
14166 if (ext->sh_size < 3)
14167 error (_("LTO Symbol extension table '%s' is empty!\n"),
14168 printable_section_name (filedata, ext));
14169 else
14171 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
14172 ext->sh_size, 1,
14173 _("LTO ext symbol data"));
14174 if (ext_data != NULL)
14176 ext_data_end = ext_data + ext->sh_size;
14177 if (* ext_data++ != 1)
14178 error (_("Unexpected version number in symbol extension table\n"));
14183 const unsigned char * data = (const unsigned char *) alloced_data;
14184 const unsigned char * end = data + section->sh_size;
14186 if (filedata->is_separate)
14187 printf (_("\nIn linked file '%s': "), filedata->file_name);
14188 else
14189 printf ("\n");
14191 if (ext_data_orig != NULL)
14193 if (do_wide)
14194 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
14195 printable_section_name (filedata, section),
14196 printable_section_name (filedata, ext));
14197 else
14199 printf (_("LTO Symbol table '%s'\n"),
14200 printable_section_name (filedata, section));
14201 printf (_(" and extension table '%s' contain:\n"),
14202 printable_section_name (filedata, ext));
14205 else
14206 printf (_("LTO Symbol table '%s' contains:\n"),
14207 printable_section_name (filedata, section));
14209 /* FIXME: Add a wide version. */
14210 if (ext_data_orig != NULL)
14211 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
14212 else
14213 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
14215 /* FIXME: We do not handle style prefixes. */
14217 while (data < end)
14219 const unsigned char * sym_name = data;
14220 data += strnlen ((const char *) sym_name, end - data) + 1;
14221 if (data >= end)
14222 goto fail;
14224 const unsigned char * comdat_key = data;
14225 data += strnlen ((const char *) comdat_key, end - data) + 1;
14226 if (data >= end)
14227 goto fail;
14229 if (data + 2 + 8 + 4 > end)
14230 goto fail;
14232 unsigned int kind = *data++;
14233 unsigned int visibility = *data++;
14235 uint64_t size = byte_get (data, 8);
14236 data += 8;
14238 uint64_t slot = byte_get (data, 4);
14239 data += 4;
14241 if (ext_data != NULL)
14243 if (ext_data < (ext_data_end - 1))
14245 unsigned int sym_type = * ext_data ++;
14246 unsigned int sec_kind = * ext_data ++;
14248 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " %9s %08x _",
14249 * comdat_key == 0 ? "-" : (char *) comdat_key,
14250 get_lto_kind (kind),
14251 get_lto_visibility (visibility),
14252 size,
14253 slot,
14254 get_lto_sym_type (sym_type),
14255 sec_kind);
14256 print_symbol_name (6, (const char *) sym_name);
14258 else
14260 error (_("Ran out of LTO symbol extension data\n"));
14261 ext_data = NULL;
14262 /* FIXME: return FAIL result ? */
14265 else
14267 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " _",
14268 * comdat_key == 0 ? "-" : (char *) comdat_key,
14269 get_lto_kind (kind),
14270 get_lto_visibility (visibility),
14271 size,
14272 slot);
14273 print_symbol_name (21, (const char *) sym_name);
14275 putchar ('\n');
14278 if (ext_data != NULL && ext_data < ext_data_end)
14280 error (_("Data remains in the LTO symbol extension table\n"));
14281 goto fail;
14284 free (alloced_data);
14285 free (ext_data_orig);
14286 free (ext_name);
14287 return true;
14289 fail:
14290 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
14291 free (alloced_data);
14292 free (ext_data_orig);
14293 free (ext_name);
14294 return false;
14297 /* Display LTO symbol tables. */
14299 static bool
14300 process_lto_symbol_tables (Filedata * filedata)
14302 Elf_Internal_Shdr * section;
14303 unsigned int i;
14304 bool res = true;
14306 if (!do_lto_syms)
14307 return true;
14309 if (filedata->section_headers == NULL)
14310 return true;
14312 for (i = 0, section = filedata->section_headers;
14313 i < filedata->file_header.e_shnum;
14314 i++, section++)
14315 if (section_name_valid (filedata, section)
14316 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
14317 res &= display_lto_symtab (filedata, section);
14319 return res;
14322 static void
14323 print_symbol_table_heading (void)
14325 /* FIXME: We should store the size of each field in the display in a table and
14326 then use the values inside print_symbol(), instead of that function using
14327 hard coded constants. */
14328 if (is_32bit_elf)
14330 if (extra_sym_info)
14332 printf (_(" Num: Value Size Type Bind Vis+Other Ndx(SecName) Name [+ Version Info]\n"));
14333 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |---8--| |----13.....| |........... */
14334 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 (.text) get_sections */
14336 else if (do_wide)
14338 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14339 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |-4| |........... */
14340 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 get_sections */
14342 else
14344 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14345 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |-4| |------------29-------------| */
14346 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 get_sections */
14349 else
14351 if (extra_sym_info)
14353 printf (_(" Num: Value Size Type Bind Vis+Other Ndx(SecName) Name [+ Version Info]\n"));
14354 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-------14---| |..... */
14355 /* eg: 2: 0000000000000000 0 FUNC LOCAL DEFAULT 1 (.text) .very_long_function_name */
14358 else if (do_wide)
14360 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14361 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-4| |........... */
14362 /* eg: 5: 0000000000000000 14 FUNC LOCAL DEFAULT 1 very_long_function_name */
14364 else
14366 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14367 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-4| |--------21---------| */
14368 /* eg: 5: 0000000000000000 14 FUNC LOCAL DEFAULT 1 very_long_functi[...] */
14373 static bool
14374 dump_symbol_section (Elf_Internal_Shdr * section,
14375 Filedata * filedata)
14377 if (section->sh_entsize == 0)
14379 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
14380 printable_section_name (filedata, section));
14381 return false;
14384 uint64_t num_syms = section->sh_size / section->sh_entsize;
14386 if (filedata->is_separate)
14387 printf (ngettext ("\nIn linked file '%s' symbol section '%s'"
14388 " contains %" PRIu64 " entry:\n",
14389 "\nIn linked file '%s' symbol section '%s'"
14390 " contains %" PRIu64 " entries:\n",
14391 num_syms),
14392 filedata->file_name,
14393 printable_section_name (filedata, section),
14394 num_syms);
14395 else
14396 printf (ngettext ("\nSymbol table '%s' contains %" PRIu64
14397 " entry:\n",
14398 "\nSymbol table '%s' contains %" PRIu64
14399 " entries:\n",
14400 num_syms),
14401 printable_section_name (filedata, section),
14402 num_syms);
14404 print_symbol_table_heading ();
14406 Elf_Internal_Sym * symtab = get_elf_symbols (filedata, section, & num_syms);
14407 if (symtab == NULL)
14408 /* An error message will have already been displayed. */
14409 return false;
14411 char * strtab = NULL;
14412 uint64_t strtab_size = 0;
14414 if (section->sh_link == filedata->file_header.e_shstrndx)
14416 strtab = filedata->string_table;
14417 strtab_size = filedata->string_table_length;
14419 else if (section->sh_link < filedata->file_header.e_shnum)
14421 Elf_Internal_Shdr * string_sec;
14423 string_sec = filedata->section_headers + section->sh_link;
14425 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
14426 1, string_sec->sh_size,
14427 _("string table"));
14428 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
14431 uint64_t si;
14433 for (si = 0; si < num_syms; si++)
14434 print_symbol (filedata, si, symtab, section, strtab, strtab_size);
14436 free (symtab);
14438 if (strtab != filedata->string_table)
14439 free (strtab);
14441 return true;
14444 /* Dump the symbol table. */
14446 static bool
14447 process_symbol_table (Filedata * filedata)
14449 Elf_Internal_Shdr * section;
14451 if (!do_syms && !do_dyn_syms && !do_histogram)
14452 return true;
14454 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
14455 && do_syms
14456 && do_using_dynamic
14457 && filedata->dynamic_strings != NULL
14458 && filedata->dynamic_symbols != NULL)
14460 uint64_t si;
14462 if (filedata->is_separate)
14464 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table"
14465 " contains %" PRIu64 " entry:\n",
14466 "\nIn linked file '%s' the dynamic symbol table"
14467 " contains %" PRIu64 " entries:\n",
14468 filedata->num_dynamic_syms),
14469 filedata->file_name,
14470 filedata->num_dynamic_syms);
14472 else
14474 printf (ngettext ("\nSymbol table for image contains %" PRIu64
14475 " entry:\n",
14476 "\nSymbol table for image contains %" PRIu64
14477 " entries:\n",
14478 filedata->num_dynamic_syms),
14479 filedata->num_dynamic_syms);
14482 print_symbol_table_heading ();
14484 for (si = 0; si < filedata->num_dynamic_syms; si++)
14485 print_symbol (filedata, si, filedata->dynamic_symbols, NULL,
14486 filedata->dynamic_strings,
14487 filedata->dynamic_strings_length);
14489 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
14490 && filedata->section_headers != NULL)
14492 unsigned int i;
14494 for (i = 0, section = filedata->section_headers;
14495 i < filedata->file_header.e_shnum;
14496 i++, section++)
14498 if ((section->sh_type != SHT_SYMTAB
14499 && section->sh_type != SHT_DYNSYM)
14500 || (!do_syms
14501 && section->sh_type == SHT_SYMTAB))
14502 continue;
14504 dump_symbol_section (section, filedata);
14507 else if (do_syms)
14508 printf
14509 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
14511 if (do_histogram && filedata->buckets != NULL)
14513 uint64_t *lengths;
14514 uint64_t *counts;
14515 uint64_t hn;
14516 uint64_t si;
14517 uint64_t maxlength = 0;
14518 uint64_t nzero_counts = 0;
14519 uint64_t nsyms = 0;
14520 char *visited;
14522 printf (ngettext ("\nHistogram for bucket list length "
14523 "(total of %" PRIu64 " bucket):\n",
14524 "\nHistogram for bucket list length "
14525 "(total of %" PRIu64 " buckets):\n",
14526 filedata->nbuckets),
14527 filedata->nbuckets);
14529 lengths = calloc (filedata->nbuckets, sizeof (*lengths));
14530 if (lengths == NULL)
14532 error (_("Out of memory allocating space for histogram buckets\n"));
14533 goto err_out;
14535 visited = xcmalloc (filedata->nchains, 1);
14536 memset (visited, 0, filedata->nchains);
14538 printf (_(" Length Number %% of total Coverage\n"));
14539 for (hn = 0; hn < filedata->nbuckets; ++hn)
14541 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
14543 ++nsyms;
14544 if (maxlength < ++lengths[hn])
14545 ++maxlength;
14546 if (si >= filedata->nchains || visited[si])
14548 error (_("histogram chain is corrupt\n"));
14549 break;
14551 visited[si] = 1;
14554 free (visited);
14556 counts = calloc (maxlength + 1, sizeof (*counts));
14557 if (counts == NULL)
14559 free (lengths);
14560 error (_("Out of memory allocating space for histogram counts\n"));
14561 goto err_out;
14564 for (hn = 0; hn < filedata->nbuckets; ++hn)
14565 ++counts[lengths[hn]];
14567 if (filedata->nbuckets > 0)
14569 uint64_t i;
14570 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
14571 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
14572 for (i = 1; i <= maxlength; ++i)
14574 nzero_counts += counts[i] * i;
14575 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
14576 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
14577 (nzero_counts * 100.0) / nsyms);
14581 free (counts);
14582 free (lengths);
14585 free (filedata->buckets);
14586 filedata->buckets = NULL;
14587 filedata->nbuckets = 0;
14588 free (filedata->chains);
14589 filedata->chains = NULL;
14591 if (do_histogram && filedata->gnubuckets != NULL)
14593 uint64_t *lengths;
14594 uint64_t *counts;
14595 uint64_t hn;
14596 uint64_t maxlength = 0;
14597 uint64_t nzero_counts = 0;
14598 uint64_t nsyms = 0;
14600 printf (ngettext ("\nHistogram for `%s' bucket list length "
14601 "(total of %" PRIu64 " bucket):\n",
14602 "\nHistogram for `%s' bucket list length "
14603 "(total of %" PRIu64 " buckets):\n",
14604 filedata->ngnubuckets),
14605 GNU_HASH_SECTION_NAME (filedata),
14606 filedata->ngnubuckets);
14608 lengths = calloc (filedata->ngnubuckets, sizeof (*lengths));
14609 if (lengths == NULL)
14611 error (_("Out of memory allocating space for gnu histogram buckets\n"));
14612 goto err_out;
14615 printf (_(" Length Number %% of total Coverage\n"));
14617 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
14618 if (filedata->gnubuckets[hn] != 0)
14620 uint64_t off, length = 1;
14622 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
14623 /* PR 17531 file: 010-77222-0.004. */
14624 off < filedata->ngnuchains
14625 && (filedata->gnuchains[off] & 1) == 0;
14626 ++off)
14627 ++length;
14628 lengths[hn] = length;
14629 if (length > maxlength)
14630 maxlength = length;
14631 nsyms += length;
14634 counts = calloc (maxlength + 1, sizeof (*counts));
14635 if (counts == NULL)
14637 free (lengths);
14638 error (_("Out of memory allocating space for gnu histogram counts\n"));
14639 goto err_out;
14642 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
14643 ++counts[lengths[hn]];
14645 if (filedata->ngnubuckets > 0)
14647 uint64_t j;
14648 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
14649 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
14650 for (j = 1; j <= maxlength; ++j)
14652 nzero_counts += counts[j] * j;
14653 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
14654 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
14655 (nzero_counts * 100.0) / nsyms);
14659 free (counts);
14660 free (lengths);
14662 free (filedata->gnubuckets);
14663 filedata->gnubuckets = NULL;
14664 filedata->ngnubuckets = 0;
14665 free (filedata->gnuchains);
14666 filedata->gnuchains = NULL;
14667 filedata->ngnuchains = 0;
14668 free (filedata->mipsxlat);
14669 filedata->mipsxlat = NULL;
14670 return true;
14672 err_out:
14673 free (filedata->gnubuckets);
14674 filedata->gnubuckets = NULL;
14675 filedata->ngnubuckets = 0;
14676 free (filedata->gnuchains);
14677 filedata->gnuchains = NULL;
14678 filedata->ngnuchains = 0;
14679 free (filedata->mipsxlat);
14680 filedata->mipsxlat = NULL;
14681 free (filedata->buckets);
14682 filedata->buckets = NULL;
14683 filedata->nbuckets = 0;
14684 free (filedata->chains);
14685 filedata->chains = NULL;
14686 return false;
14689 static bool
14690 process_syminfo (Filedata * filedata)
14692 unsigned int i;
14694 if (filedata->dynamic_syminfo == NULL
14695 || !do_dynamic)
14696 /* No syminfo, this is ok. */
14697 return true;
14699 /* There better should be a dynamic symbol section. */
14700 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
14701 return false;
14703 if (filedata->is_separate)
14704 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entry:\n",
14705 "\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entries:\n",
14706 filedata->dynamic_syminfo_nent),
14707 filedata->file_name,
14708 filedata->dynamic_syminfo_offset,
14709 filedata->dynamic_syminfo_nent);
14710 else
14711 printf (ngettext ("\nDynamic info segment at offset %#" PRIx64
14712 " contains %d entry:\n",
14713 "\nDynamic info segment at offset %#" PRIx64
14714 " contains %d entries:\n",
14715 filedata->dynamic_syminfo_nent),
14716 filedata->dynamic_syminfo_offset,
14717 filedata->dynamic_syminfo_nent);
14719 printf (_(" Num: Name BoundTo Flags\n"));
14720 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
14722 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
14724 printf ("%4d: ", i);
14725 if (i >= filedata->num_dynamic_syms)
14726 printf (_("<corrupt index>"));
14727 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
14728 print_symbol_name (30, get_dynamic_name (filedata,
14729 filedata->dynamic_symbols[i].st_name));
14730 else
14731 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
14732 putchar (' ');
14734 switch (filedata->dynamic_syminfo[i].si_boundto)
14736 case SYMINFO_BT_SELF:
14737 fputs ("SELF ", stdout);
14738 break;
14739 case SYMINFO_BT_PARENT:
14740 fputs ("PARENT ", stdout);
14741 break;
14742 default:
14743 if (filedata->dynamic_syminfo[i].si_boundto > 0
14744 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
14745 && valid_dynamic_name (filedata,
14746 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
14748 print_symbol_name (10, get_dynamic_name (filedata,
14749 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
14750 putchar (' ' );
14752 else
14753 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
14754 break;
14757 if (flags & SYMINFO_FLG_DIRECT)
14758 printf (" DIRECT");
14759 if (flags & SYMINFO_FLG_PASSTHRU)
14760 printf (" PASSTHRU");
14761 if (flags & SYMINFO_FLG_COPY)
14762 printf (" COPY");
14763 if (flags & SYMINFO_FLG_LAZYLOAD)
14764 printf (" LAZYLOAD");
14766 puts ("");
14769 return true;
14772 /* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
14773 is contained by the region START .. END. The types of ADDR, START
14774 and END should all be the same. Note both ADDR + NELEM and END
14775 point to just beyond the end of the regions that are being tested. */
14776 #define IN_RANGE(START,END,ADDR,NELEM) \
14777 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
14779 /* Check to see if the given reloc needs to be handled in a target specific
14780 manner. If so then process the reloc and return TRUE otherwise return
14781 FALSE.
14783 If called with reloc == NULL, then this is a signal that reloc processing
14784 for the current section has finished, and any saved state should be
14785 discarded. */
14787 static bool
14788 target_specific_reloc_handling (Filedata *filedata,
14789 Elf_Internal_Rela *reloc,
14790 unsigned char *start,
14791 unsigned char *end,
14792 Elf_Internal_Sym *symtab,
14793 uint64_t num_syms)
14795 unsigned int reloc_type = 0;
14796 uint64_t sym_index = 0;
14798 if (reloc)
14800 reloc_type = get_reloc_type (filedata, reloc->r_info);
14801 sym_index = get_reloc_symindex (reloc->r_info);
14804 switch (filedata->file_header.e_machine)
14806 case EM_LOONGARCH:
14808 switch (reloc_type)
14810 /* For .uleb128 .LFE1-.LFB1, loongarch write 0 to object file
14811 at assembly time. */
14812 case 107: /* R_LARCH_ADD_ULEB128. */
14813 case 108: /* R_LARCH_SUB_ULEB128. */
14815 uint64_t value = 0;
14816 unsigned int reloc_size = 0;
14817 int leb_ret = 0;
14819 if (reloc->r_offset < (size_t) (end - start))
14820 value = read_leb128 (start + reloc->r_offset, end, false,
14821 &reloc_size, &leb_ret);
14822 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
14823 error (_("LoongArch ULEB128 field at 0x%lx contains invalid "
14824 "ULEB128 value\n"),
14825 (long) reloc->r_offset);
14827 else if (sym_index >= num_syms)
14828 error (_("%s reloc contains invalid symbol index "
14829 "%" PRIu64 "\n"),
14830 (reloc_type == 107
14831 ? "R_LARCH_ADD_ULEB128"
14832 : "R_LARCH_SUB_ULEB128"),
14833 sym_index);
14834 else
14836 if (reloc_type == 107)
14837 value += reloc->r_addend + symtab[sym_index].st_value;
14838 else
14839 value -= reloc->r_addend + symtab[sym_index].st_value;
14841 /* Write uleb128 value to p. */
14842 bfd_byte *p = start + reloc->r_offset;
14845 bfd_byte c = value & 0x7f;
14846 value >>= 7;
14847 if (--reloc_size != 0)
14848 c |= 0x80;
14849 *p++ = c;
14851 while (reloc_size);
14854 return true;
14857 break;
14860 case EM_MSP430:
14861 case EM_MSP430_OLD:
14863 static Elf_Internal_Sym * saved_sym = NULL;
14865 if (reloc == NULL)
14867 saved_sym = NULL;
14868 return true;
14871 switch (reloc_type)
14873 case 10: /* R_MSP430_SYM_DIFF */
14874 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
14875 if (uses_msp430x_relocs (filedata))
14876 break;
14877 /* Fall through. */
14878 case 21: /* R_MSP430X_SYM_DIFF */
14879 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
14880 /* PR 21139. */
14881 if (sym_index >= num_syms)
14882 error (_("%s reloc contains invalid symbol index "
14883 "%" PRIu64 "\n"), "MSP430 SYM_DIFF", sym_index);
14884 else
14885 saved_sym = symtab + sym_index;
14886 return true;
14888 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14889 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
14890 goto handle_sym_diff;
14892 case 5: /* R_MSP430_16_BYTE */
14893 case 9: /* R_MSP430_8 */
14894 case 11: /* R_MSP430_GNU_SET_ULEB128 */
14895 if (uses_msp430x_relocs (filedata))
14896 break;
14897 goto handle_sym_diff;
14899 case 2: /* R_MSP430_ABS16 */
14900 case 15: /* R_MSP430X_ABS16 */
14901 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
14902 if (! uses_msp430x_relocs (filedata))
14903 break;
14904 goto handle_sym_diff;
14906 handle_sym_diff:
14907 if (saved_sym != NULL)
14909 uint64_t value;
14910 unsigned int reloc_size = 0;
14911 int leb_ret = 0;
14912 switch (reloc_type)
14914 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14915 reloc_size = 4;
14916 break;
14917 case 11: /* R_MSP430_GNU_SET_ULEB128 */
14918 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
14919 if (reloc->r_offset < (size_t) (end - start))
14920 read_leb128 (start + reloc->r_offset, end, false,
14921 &reloc_size, &leb_ret);
14922 break;
14923 default:
14924 reloc_size = 2;
14925 break;
14928 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
14929 error (_("MSP430 ULEB128 field at %#" PRIx64
14930 " contains invalid ULEB128 value\n"),
14931 reloc->r_offset);
14932 else if (sym_index >= num_syms)
14933 error (_("%s reloc contains invalid symbol index "
14934 "%" PRIu64 "\n"), "MSP430", sym_index);
14935 else
14937 value = reloc->r_addend + (symtab[sym_index].st_value
14938 - saved_sym->st_value);
14940 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
14941 byte_put (start + reloc->r_offset, value, reloc_size);
14942 else
14943 /* PR 21137 */
14944 error (_("MSP430 sym diff reloc contains invalid offset: "
14945 "%#" PRIx64 "\n"),
14946 reloc->r_offset);
14949 saved_sym = NULL;
14950 return true;
14952 break;
14954 default:
14955 if (saved_sym != NULL)
14956 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
14957 break;
14959 break;
14962 case EM_MN10300:
14963 case EM_CYGNUS_MN10300:
14965 static Elf_Internal_Sym * saved_sym = NULL;
14967 if (reloc == NULL)
14969 saved_sym = NULL;
14970 return true;
14973 switch (reloc_type)
14975 case 34: /* R_MN10300_ALIGN */
14976 return true;
14977 case 33: /* R_MN10300_SYM_DIFF */
14978 if (sym_index >= num_syms)
14979 error (_("%s reloc contains invalid symbol index "
14980 "%" PRIu64 "\n"), "MN10300_SYM_DIFF", sym_index);
14981 else
14982 saved_sym = symtab + sym_index;
14983 return true;
14985 case 1: /* R_MN10300_32 */
14986 case 2: /* R_MN10300_16 */
14987 if (saved_sym != NULL)
14989 int reloc_size = reloc_type == 1 ? 4 : 2;
14990 uint64_t value;
14992 if (sym_index >= num_syms)
14993 error (_("%s reloc contains invalid symbol index "
14994 "%" PRIu64 "\n"), "MN10300", sym_index);
14995 else
14997 value = reloc->r_addend + (symtab[sym_index].st_value
14998 - saved_sym->st_value);
15000 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
15001 byte_put (start + reloc->r_offset, value, reloc_size);
15002 else
15003 error (_("MN10300 sym diff reloc contains invalid offset:"
15004 " %#" PRIx64 "\n"),
15005 reloc->r_offset);
15008 saved_sym = NULL;
15009 return true;
15011 break;
15012 default:
15013 if (saved_sym != NULL)
15014 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
15015 break;
15017 break;
15020 case EM_RL78:
15022 static uint64_t saved_sym1 = 0;
15023 static uint64_t saved_sym2 = 0;
15024 static uint64_t value;
15026 if (reloc == NULL)
15028 saved_sym1 = saved_sym2 = 0;
15029 return true;
15032 switch (reloc_type)
15034 case 0x80: /* R_RL78_SYM. */
15035 saved_sym1 = saved_sym2;
15036 if (sym_index >= num_syms)
15037 error (_("%s reloc contains invalid symbol index "
15038 "%" PRIu64 "\n"), "RL78_SYM", sym_index);
15039 else
15041 saved_sym2 = symtab[sym_index].st_value;
15042 saved_sym2 += reloc->r_addend;
15044 return true;
15046 case 0x83: /* R_RL78_OPsub. */
15047 value = saved_sym1 - saved_sym2;
15048 saved_sym2 = saved_sym1 = 0;
15049 return true;
15050 break;
15052 case 0x41: /* R_RL78_ABS32. */
15053 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
15054 byte_put (start + reloc->r_offset, value, 4);
15055 else
15056 error (_("RL78 sym diff reloc contains invalid offset: "
15057 "%#" PRIx64 "\n"),
15058 reloc->r_offset);
15059 value = 0;
15060 return true;
15062 case 0x43: /* R_RL78_ABS16. */
15063 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
15064 byte_put (start + reloc->r_offset, value, 2);
15065 else
15066 error (_("RL78 sym diff reloc contains invalid offset: "
15067 "%#" PRIx64 "\n"),
15068 reloc->r_offset);
15069 value = 0;
15070 return true;
15072 default:
15073 break;
15075 break;
15079 return false;
15082 /* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
15083 DWARF debug sections. This is a target specific test. Note - we do not
15084 go through the whole including-target-headers-multiple-times route, (as
15085 we have already done with <elf/h8.h>) because this would become very
15086 messy and even then this function would have to contain target specific
15087 information (the names of the relocs instead of their numeric values).
15088 FIXME: This is not the correct way to solve this problem. The proper way
15089 is to have target specific reloc sizing and typing functions created by
15090 the reloc-macros.h header, in the same way that it already creates the
15091 reloc naming functions. */
15093 static bool
15094 is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15096 /* Please keep this table alpha-sorted for ease of visual lookup. */
15097 switch (filedata->file_header.e_machine)
15099 case EM_386:
15100 case EM_IAMCU:
15101 return reloc_type == 1; /* R_386_32. */
15102 case EM_68K:
15103 return reloc_type == 1; /* R_68K_32. */
15104 case EM_860:
15105 return reloc_type == 1; /* R_860_32. */
15106 case EM_960:
15107 return reloc_type == 2; /* R_960_32. */
15108 case EM_AARCH64:
15109 return (reloc_type == 258
15110 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
15111 case EM_BPF:
15112 return reloc_type == 11; /* R_BPF_DATA_32 */
15113 case EM_ADAPTEVA_EPIPHANY:
15114 return reloc_type == 3;
15115 case EM_ALPHA:
15116 return reloc_type == 1; /* R_ALPHA_REFLONG. */
15117 case EM_ARC:
15118 return reloc_type == 1; /* R_ARC_32. */
15119 case EM_ARC_COMPACT:
15120 case EM_ARC_COMPACT2:
15121 case EM_ARC_COMPACT3:
15122 case EM_ARC_COMPACT3_64:
15123 return reloc_type == 4; /* R_ARC_32. */
15124 case EM_ARM:
15125 return reloc_type == 2; /* R_ARM_ABS32 */
15126 case EM_AVR_OLD:
15127 case EM_AVR:
15128 return reloc_type == 1;
15129 case EM_BLACKFIN:
15130 return reloc_type == 0x12; /* R_byte4_data. */
15131 case EM_CRIS:
15132 return reloc_type == 3; /* R_CRIS_32. */
15133 case EM_CR16:
15134 return reloc_type == 3; /* R_CR16_NUM32. */
15135 case EM_CRX:
15136 return reloc_type == 15; /* R_CRX_NUM32. */
15137 case EM_CSKY:
15138 return reloc_type == 1; /* R_CKCORE_ADDR32. */
15139 case EM_CYGNUS_FRV:
15140 return reloc_type == 1;
15141 case EM_CYGNUS_D10V:
15142 case EM_D10V:
15143 return reloc_type == 6; /* R_D10V_32. */
15144 case EM_CYGNUS_D30V:
15145 case EM_D30V:
15146 return reloc_type == 12; /* R_D30V_32_NORMAL. */
15147 case EM_DLX:
15148 return reloc_type == 3; /* R_DLX_RELOC_32. */
15149 case EM_CYGNUS_FR30:
15150 case EM_FR30:
15151 return reloc_type == 3; /* R_FR30_32. */
15152 case EM_FT32:
15153 return reloc_type == 1; /* R_FT32_32. */
15154 case EM_H8S:
15155 case EM_H8_300:
15156 case EM_H8_300H:
15157 return reloc_type == 1; /* R_H8_DIR32. */
15158 case EM_IA_64:
15159 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
15160 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
15161 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
15162 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
15163 case EM_IP2K_OLD:
15164 case EM_IP2K:
15165 return reloc_type == 2; /* R_IP2K_32. */
15166 case EM_IQ2000:
15167 return reloc_type == 2; /* R_IQ2000_32. */
15168 case EM_KVX:
15169 return reloc_type == 2; /* R_KVX_32. */
15170 case EM_LATTICEMICO32:
15171 return reloc_type == 3; /* R_LM32_32. */
15172 case EM_LOONGARCH:
15173 return reloc_type == 1; /* R_LARCH_32. */
15174 case EM_M32C_OLD:
15175 case EM_M32C:
15176 return reloc_type == 3; /* R_M32C_32. */
15177 case EM_M32R:
15178 return reloc_type == 34; /* R_M32R_32_RELA. */
15179 case EM_68HC11:
15180 case EM_68HC12:
15181 return reloc_type == 6; /* R_M68HC11_32. */
15182 case EM_S12Z:
15183 return reloc_type == 7 || /* R_S12Z_EXT32 */
15184 reloc_type == 6; /* R_S12Z_CW32. */
15185 case EM_MCORE:
15186 return reloc_type == 1; /* R_MCORE_ADDR32. */
15187 case EM_CYGNUS_MEP:
15188 return reloc_type == 4; /* R_MEP_32. */
15189 case EM_METAG:
15190 return reloc_type == 2; /* R_METAG_ADDR32. */
15191 case EM_MICROBLAZE:
15192 return reloc_type == 1; /* R_MICROBLAZE_32. */
15193 case EM_MIPS:
15194 return reloc_type == 2; /* R_MIPS_32. */
15195 case EM_MMIX:
15196 return reloc_type == 4; /* R_MMIX_32. */
15197 case EM_CYGNUS_MN10200:
15198 case EM_MN10200:
15199 return reloc_type == 1; /* R_MN10200_32. */
15200 case EM_CYGNUS_MN10300:
15201 case EM_MN10300:
15202 return reloc_type == 1; /* R_MN10300_32. */
15203 case EM_MOXIE:
15204 return reloc_type == 1; /* R_MOXIE_32. */
15205 case EM_MSP430_OLD:
15206 case EM_MSP430:
15207 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
15208 case EM_MT:
15209 return reloc_type == 2; /* R_MT_32. */
15210 case EM_NDS32:
15211 return reloc_type == 20; /* R_NDS32_32_RELA. */
15212 case EM_ALTERA_NIOS2:
15213 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
15214 case EM_NIOS32:
15215 return reloc_type == 1; /* R_NIOS_32. */
15216 case EM_OR1K:
15217 return reloc_type == 1; /* R_OR1K_32. */
15218 case EM_PARISC:
15219 return (reloc_type == 1 /* R_PARISC_DIR32. */
15220 || reloc_type == 2 /* R_PARISC_DIR21L. */
15221 || reloc_type == 41); /* R_PARISC_SECREL32. */
15222 case EM_PJ:
15223 case EM_PJ_OLD:
15224 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
15225 case EM_PPC64:
15226 return reloc_type == 1; /* R_PPC64_ADDR32. */
15227 case EM_PPC:
15228 return reloc_type == 1; /* R_PPC_ADDR32. */
15229 case EM_TI_PRU:
15230 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
15231 case EM_RISCV:
15232 return reloc_type == 1; /* R_RISCV_32. */
15233 case EM_RL78:
15234 return reloc_type == 1; /* R_RL78_DIR32. */
15235 case EM_RX:
15236 return reloc_type == 1; /* R_RX_DIR32. */
15237 case EM_S370:
15238 return reloc_type == 1; /* R_I370_ADDR31. */
15239 case EM_S390_OLD:
15240 case EM_S390:
15241 return reloc_type == 4; /* R_S390_32. */
15242 case EM_SCORE:
15243 return reloc_type == 8; /* R_SCORE_ABS32. */
15244 case EM_SH:
15245 return reloc_type == 1; /* R_SH_DIR32. */
15246 case EM_SPARC32PLUS:
15247 case EM_SPARCV9:
15248 case EM_SPARC:
15249 return reloc_type == 3 /* R_SPARC_32. */
15250 || reloc_type == 23; /* R_SPARC_UA32. */
15251 case EM_SPU:
15252 return reloc_type == 6; /* R_SPU_ADDR32 */
15253 case EM_TI_C6000:
15254 return reloc_type == 1; /* R_C6000_ABS32. */
15255 case EM_TILEGX:
15256 return reloc_type == 2; /* R_TILEGX_32. */
15257 case EM_TILEPRO:
15258 return reloc_type == 1; /* R_TILEPRO_32. */
15259 case EM_CYGNUS_V850:
15260 case EM_V850:
15261 return reloc_type == 6; /* R_V850_ABS32. */
15262 case EM_V800:
15263 return reloc_type == 0x33; /* R_V810_WORD. */
15264 case EM_VAX:
15265 return reloc_type == 1; /* R_VAX_32. */
15266 case EM_VISIUM:
15267 return reloc_type == 3; /* R_VISIUM_32. */
15268 case EM_WEBASSEMBLY:
15269 return reloc_type == 1; /* R_WASM32_32. */
15270 case EM_X86_64:
15271 case EM_L1OM:
15272 case EM_K1OM:
15273 return reloc_type == 10; /* R_X86_64_32. */
15274 case EM_XGATE:
15275 return reloc_type == 4; /* R_XGATE_32. */
15276 case EM_XSTORMY16:
15277 return reloc_type == 1; /* R_XSTROMY16_32. */
15278 case EM_XTENSA_OLD:
15279 case EM_XTENSA:
15280 return reloc_type == 1; /* R_XTENSA_32. */
15281 case EM_Z80:
15282 return reloc_type == 6; /* R_Z80_32. */
15283 default:
15285 static unsigned int prev_warn = 0;
15287 /* Avoid repeating the same warning multiple times. */
15288 if (prev_warn != filedata->file_header.e_machine)
15289 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
15290 filedata->file_header.e_machine);
15291 prev_warn = filedata->file_header.e_machine;
15292 return false;
15297 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15298 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
15300 static bool
15301 is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
15303 switch (filedata->file_header.e_machine)
15304 /* Please keep this table alpha-sorted for ease of visual lookup. */
15306 case EM_386:
15307 case EM_IAMCU:
15308 return reloc_type == 2; /* R_386_PC32. */
15309 case EM_68K:
15310 return reloc_type == 4; /* R_68K_PC32. */
15311 case EM_AARCH64:
15312 return reloc_type == 261; /* R_AARCH64_PREL32 */
15313 case EM_ADAPTEVA_EPIPHANY:
15314 return reloc_type == 6;
15315 case EM_ALPHA:
15316 return reloc_type == 10; /* R_ALPHA_SREL32. */
15317 case EM_ARC_COMPACT:
15318 case EM_ARC_COMPACT2:
15319 case EM_ARC_COMPACT3:
15320 case EM_ARC_COMPACT3_64:
15321 return reloc_type == 49; /* R_ARC_32_PCREL. */
15322 case EM_ARM:
15323 return reloc_type == 3; /* R_ARM_REL32 */
15324 case EM_AVR_OLD:
15325 case EM_AVR:
15326 return reloc_type == 36; /* R_AVR_32_PCREL. */
15327 case EM_LOONGARCH:
15328 return reloc_type == 99; /* R_LARCH_32_PCREL. */
15329 case EM_MICROBLAZE:
15330 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
15331 case EM_OR1K:
15332 return reloc_type == 9; /* R_OR1K_32_PCREL. */
15333 case EM_PARISC:
15334 return reloc_type == 9; /* R_PARISC_PCREL32. */
15335 case EM_PPC:
15336 return reloc_type == 26; /* R_PPC_REL32. */
15337 case EM_PPC64:
15338 return reloc_type == 26; /* R_PPC64_REL32. */
15339 case EM_RISCV:
15340 return reloc_type == 57; /* R_RISCV_32_PCREL. */
15341 case EM_S390_OLD:
15342 case EM_S390:
15343 return reloc_type == 5; /* R_390_PC32. */
15344 case EM_SH:
15345 return reloc_type == 2; /* R_SH_REL32. */
15346 case EM_SPARC32PLUS:
15347 case EM_SPARCV9:
15348 case EM_SPARC:
15349 return reloc_type == 6; /* R_SPARC_DISP32. */
15350 case EM_SPU:
15351 return reloc_type == 13; /* R_SPU_REL32. */
15352 case EM_TILEGX:
15353 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
15354 case EM_TILEPRO:
15355 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
15356 case EM_VISIUM:
15357 return reloc_type == 6; /* R_VISIUM_32_PCREL */
15358 case EM_X86_64:
15359 case EM_L1OM:
15360 case EM_K1OM:
15361 return reloc_type == 2; /* R_X86_64_PC32. */
15362 case EM_VAX:
15363 return reloc_type == 4; /* R_VAX_PCREL32. */
15364 case EM_XTENSA_OLD:
15365 case EM_XTENSA:
15366 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
15367 case EM_KVX:
15368 return reloc_type == 7; /* R_KVX_32_PCREL */
15369 default:
15370 /* Do not abort or issue an error message here. Not all targets use
15371 pc-relative 32-bit relocs in their DWARF debug information and we
15372 have already tested for target coverage in is_32bit_abs_reloc. A
15373 more helpful warning message will be generated by apply_relocations
15374 anyway, so just return. */
15375 return false;
15379 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15380 a 64-bit absolute RELA relocation used in DWARF debug sections. */
15382 static bool
15383 is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15385 switch (filedata->file_header.e_machine)
15387 case EM_AARCH64:
15388 return reloc_type == 257; /* R_AARCH64_ABS64. */
15389 case EM_ARC_COMPACT3_64:
15390 return reloc_type == 5; /* R_ARC_64. */
15391 case EM_ALPHA:
15392 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
15393 case EM_IA_64:
15394 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
15395 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
15396 case EM_LOONGARCH:
15397 return reloc_type == 2; /* R_LARCH_64 */
15398 case EM_PARISC:
15399 return reloc_type == 80; /* R_PARISC_DIR64. */
15400 case EM_PPC64:
15401 return reloc_type == 38; /* R_PPC64_ADDR64. */
15402 case EM_RISCV:
15403 return reloc_type == 2; /* R_RISCV_64. */
15404 case EM_SPARC32PLUS:
15405 case EM_SPARCV9:
15406 case EM_SPARC:
15407 return reloc_type == 32 /* R_SPARC_64. */
15408 || reloc_type == 54; /* R_SPARC_UA64. */
15409 case EM_X86_64:
15410 case EM_L1OM:
15411 case EM_K1OM:
15412 return reloc_type == 1; /* R_X86_64_64. */
15413 case EM_S390_OLD:
15414 case EM_S390:
15415 return reloc_type == 22; /* R_S390_64. */
15416 case EM_TILEGX:
15417 return reloc_type == 1; /* R_TILEGX_64. */
15418 case EM_MIPS:
15419 return reloc_type == 18; /* R_MIPS_64. */
15420 case EM_KVX:
15421 return reloc_type == 3; /* R_KVX_64 */
15422 default:
15423 return false;
15427 /* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
15428 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
15430 static bool
15431 is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
15433 switch (filedata->file_header.e_machine)
15435 case EM_AARCH64:
15436 return reloc_type == 260; /* R_AARCH64_PREL64. */
15437 case EM_ALPHA:
15438 return reloc_type == 11; /* R_ALPHA_SREL64. */
15439 case EM_IA_64:
15440 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
15441 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
15442 case EM_PARISC:
15443 return reloc_type == 72; /* R_PARISC_PCREL64. */
15444 case EM_PPC64:
15445 return reloc_type == 44; /* R_PPC64_REL64. */
15446 case EM_SPARC32PLUS:
15447 case EM_SPARCV9:
15448 case EM_SPARC:
15449 return reloc_type == 46; /* R_SPARC_DISP64. */
15450 case EM_X86_64:
15451 case EM_L1OM:
15452 case EM_K1OM:
15453 return reloc_type == 24; /* R_X86_64_PC64. */
15454 case EM_S390_OLD:
15455 case EM_S390:
15456 return reloc_type == 23; /* R_S390_PC64. */
15457 case EM_TILEGX:
15458 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
15459 default:
15460 return false;
15464 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15465 a 24-bit absolute RELA relocation used in DWARF debug sections. */
15467 static bool
15468 is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15470 switch (filedata->file_header.e_machine)
15472 case EM_CYGNUS_MN10200:
15473 case EM_MN10200:
15474 return reloc_type == 4; /* R_MN10200_24. */
15475 case EM_FT32:
15476 return reloc_type == 5; /* R_FT32_20. */
15477 case EM_Z80:
15478 return reloc_type == 5; /* R_Z80_24. */
15479 default:
15480 return false;
15484 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15485 a 16-bit absolute RELA relocation used in DWARF debug sections. */
15487 static bool
15488 is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15490 /* Please keep this table alpha-sorted for ease of visual lookup. */
15491 switch (filedata->file_header.e_machine)
15493 case EM_ARC:
15494 case EM_ARC_COMPACT:
15495 case EM_ARC_COMPACT2:
15496 case EM_ARC_COMPACT3:
15497 case EM_ARC_COMPACT3_64:
15498 return reloc_type == 2; /* R_ARC_16. */
15499 case EM_ADAPTEVA_EPIPHANY:
15500 return reloc_type == 5;
15501 case EM_AVR_OLD:
15502 case EM_AVR:
15503 return reloc_type == 4; /* R_AVR_16. */
15504 case EM_CYGNUS_D10V:
15505 case EM_D10V:
15506 return reloc_type == 3; /* R_D10V_16. */
15507 case EM_FT32:
15508 return reloc_type == 2; /* R_FT32_16. */
15509 case EM_H8S:
15510 case EM_H8_300:
15511 case EM_H8_300H:
15512 return reloc_type == R_H8_DIR16;
15513 case EM_IP2K_OLD:
15514 case EM_IP2K:
15515 return reloc_type == 1; /* R_IP2K_16. */
15516 case EM_M32C_OLD:
15517 case EM_M32C:
15518 return reloc_type == 1; /* R_M32C_16 */
15519 case EM_CYGNUS_MN10200:
15520 case EM_MN10200:
15521 return reloc_type == 2; /* R_MN10200_16. */
15522 case EM_CYGNUS_MN10300:
15523 case EM_MN10300:
15524 return reloc_type == 2; /* R_MN10300_16. */
15525 case EM_KVX:
15526 return reloc_type == 1; /* R_KVX_16 */
15527 case EM_MSP430:
15528 if (uses_msp430x_relocs (filedata))
15529 return reloc_type == 2; /* R_MSP430_ABS16. */
15530 /* Fall through. */
15531 case EM_MSP430_OLD:
15532 return reloc_type == 5; /* R_MSP430_16_BYTE. */
15533 case EM_NDS32:
15534 return reloc_type == 19; /* R_NDS32_16_RELA. */
15535 case EM_ALTERA_NIOS2:
15536 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
15537 case EM_NIOS32:
15538 return reloc_type == 9; /* R_NIOS_16. */
15539 case EM_OR1K:
15540 return reloc_type == 2; /* R_OR1K_16. */
15541 case EM_RISCV:
15542 return reloc_type == 55; /* R_RISCV_SET16. */
15543 case EM_TI_PRU:
15544 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
15545 case EM_TI_C6000:
15546 return reloc_type == 2; /* R_C6000_ABS16. */
15547 case EM_VISIUM:
15548 return reloc_type == 2; /* R_VISIUM_16. */
15549 case EM_XGATE:
15550 return reloc_type == 3; /* R_XGATE_16. */
15551 case EM_Z80:
15552 return reloc_type == 4; /* R_Z80_16. */
15553 default:
15554 return false;
15558 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15559 a 8-bit absolute RELA relocation used in DWARF debug sections. */
15561 static bool
15562 is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15564 switch (filedata->file_header.e_machine)
15566 case EM_RISCV:
15567 return reloc_type == 54; /* R_RISCV_SET8. */
15568 case EM_Z80:
15569 return reloc_type == 1; /* R_Z80_8. */
15570 case EM_MICROBLAZE:
15571 return (reloc_type == 33 /* R_MICROBLAZE_32_NONE. */
15572 || reloc_type == 0 /* R_MICROBLAZE_NONE. */
15573 || reloc_type == 9 /* R_MICROBLAZE_64_NONE. */);
15574 default:
15575 return false;
15579 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15580 a 6-bit absolute RELA relocation used in DWARF debug sections. */
15582 static bool
15583 is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15585 switch (filedata->file_header.e_machine)
15587 case EM_RISCV:
15588 return reloc_type == 53; /* R_RISCV_SET6. */
15589 default:
15590 return false;
15594 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15595 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
15597 static bool
15598 is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15600 /* Please keep this table alpha-sorted for ease of visual lookup. */
15601 switch (filedata->file_header.e_machine)
15603 case EM_LOONGARCH:
15604 return reloc_type == 50; /* R_LARCH_ADD32. */
15605 case EM_RISCV:
15606 return reloc_type == 35; /* R_RISCV_ADD32. */
15607 default:
15608 return false;
15612 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15613 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
15615 static bool
15616 is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15618 /* Please keep this table alpha-sorted for ease of visual lookup. */
15619 switch (filedata->file_header.e_machine)
15621 case EM_LOONGARCH:
15622 return reloc_type == 55; /* R_LARCH_SUB32. */
15623 case EM_RISCV:
15624 return reloc_type == 39; /* R_RISCV_SUB32. */
15625 default:
15626 return false;
15630 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15631 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
15633 static bool
15634 is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15636 /* Please keep this table alpha-sorted for ease of visual lookup. */
15637 switch (filedata->file_header.e_machine)
15639 case EM_LOONGARCH:
15640 return reloc_type == 51; /* R_LARCH_ADD64. */
15641 case EM_RISCV:
15642 return reloc_type == 36; /* R_RISCV_ADD64. */
15643 default:
15644 return false;
15648 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15649 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
15651 static bool
15652 is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15654 /* Please keep this table alpha-sorted for ease of visual lookup. */
15655 switch (filedata->file_header.e_machine)
15657 case EM_LOONGARCH:
15658 return reloc_type == 56; /* R_LARCH_SUB64. */
15659 case EM_RISCV:
15660 return reloc_type == 40; /* R_RISCV_SUB64. */
15661 default:
15662 return false;
15666 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15667 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
15669 static bool
15670 is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15672 /* Please keep this table alpha-sorted for ease of visual lookup. */
15673 switch (filedata->file_header.e_machine)
15675 case EM_LOONGARCH:
15676 return reloc_type == 48; /* R_LARCH_ADD16. */
15677 case EM_RISCV:
15678 return reloc_type == 34; /* R_RISCV_ADD16. */
15679 default:
15680 return false;
15684 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15685 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
15687 static bool
15688 is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15690 /* Please keep this table alpha-sorted for ease of visual lookup. */
15691 switch (filedata->file_header.e_machine)
15693 case EM_LOONGARCH:
15694 return reloc_type == 53; /* R_LARCH_SUB16. */
15695 case EM_RISCV:
15696 return reloc_type == 38; /* R_RISCV_SUB16. */
15697 default:
15698 return false;
15702 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15703 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
15705 static bool
15706 is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15708 /* Please keep this table alpha-sorted for ease of visual lookup. */
15709 switch (filedata->file_header.e_machine)
15711 case EM_LOONGARCH:
15712 return reloc_type == 47; /* R_LARCH_ADD8. */
15713 case EM_RISCV:
15714 return reloc_type == 33; /* R_RISCV_ADD8. */
15715 default:
15716 return false;
15720 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15721 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
15723 static bool
15724 is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15726 /* Please keep this table alpha-sorted for ease of visual lookup. */
15727 switch (filedata->file_header.e_machine)
15729 case EM_LOONGARCH:
15730 return reloc_type == 52; /* R_LARCH_SUB8. */
15731 case EM_RISCV:
15732 return reloc_type == 37; /* R_RISCV_SUB8. */
15733 default:
15734 return false;
15738 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15739 a 6-bit inplace add RELA relocation used in DWARF debug sections. */
15741 static bool
15742 is_6bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15744 switch (filedata->file_header.e_machine)
15746 case EM_LOONGARCH:
15747 return reloc_type == 105; /* R_LARCH_ADD6. */
15748 default:
15749 return false;
15753 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15754 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
15756 static bool
15757 is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15759 switch (filedata->file_header.e_machine)
15761 case EM_LOONGARCH:
15762 return reloc_type == 106; /* R_LARCH_SUB6. */
15763 case EM_RISCV:
15764 return reloc_type == 52; /* R_RISCV_SUB6. */
15765 default:
15766 return false;
15770 /* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
15771 relocation entries (possibly formerly used for SHT_GROUP sections). */
15773 static bool
15774 is_none_reloc (Filedata * filedata, unsigned int reloc_type)
15776 switch (filedata->file_header.e_machine)
15778 case EM_386: /* R_386_NONE. */
15779 case EM_68K: /* R_68K_NONE. */
15780 case EM_ADAPTEVA_EPIPHANY:
15781 case EM_ALPHA: /* R_ALPHA_NONE. */
15782 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
15783 case EM_ARC: /* R_ARC_NONE. */
15784 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
15785 case EM_ARC_COMPACT: /* R_ARC_NONE. */
15786 case EM_ARC_COMPACT3: /* R_ARC_NONE. */
15787 case EM_ARC_COMPACT3_64: /* R_ARC_NONE. */
15788 case EM_ARM: /* R_ARM_NONE. */
15789 case EM_CRIS: /* R_CRIS_NONE. */
15790 case EM_FT32: /* R_FT32_NONE. */
15791 case EM_IA_64: /* R_IA64_NONE. */
15792 case EM_K1OM: /* R_X86_64_NONE. */
15793 case EM_KVX: /* R_KVX_NONE. */
15794 case EM_L1OM: /* R_X86_64_NONE. */
15795 case EM_M32R: /* R_M32R_NONE. */
15796 case EM_MIPS: /* R_MIPS_NONE. */
15797 case EM_MN10300: /* R_MN10300_NONE. */
15798 case EM_MOXIE: /* R_MOXIE_NONE. */
15799 case EM_NIOS32: /* R_NIOS_NONE. */
15800 case EM_OR1K: /* R_OR1K_NONE. */
15801 case EM_PARISC: /* R_PARISC_NONE. */
15802 case EM_PPC64: /* R_PPC64_NONE. */
15803 case EM_PPC: /* R_PPC_NONE. */
15804 case EM_RISCV: /* R_RISCV_NONE. */
15805 case EM_S390: /* R_390_NONE. */
15806 case EM_S390_OLD:
15807 case EM_SH: /* R_SH_NONE. */
15808 case EM_SPARC32PLUS:
15809 case EM_SPARC: /* R_SPARC_NONE. */
15810 case EM_SPARCV9:
15811 case EM_TILEGX: /* R_TILEGX_NONE. */
15812 case EM_TILEPRO: /* R_TILEPRO_NONE. */
15813 case EM_TI_C6000:/* R_C6000_NONE. */
15814 case EM_X86_64: /* R_X86_64_NONE. */
15815 case EM_Z80: /* R_Z80_NONE. */
15816 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
15817 return reloc_type == 0;
15819 case EM_AARCH64:
15820 return reloc_type == 0 || reloc_type == 256;
15821 case EM_AVR_OLD:
15822 case EM_AVR:
15823 return (reloc_type == 0 /* R_AVR_NONE. */
15824 || reloc_type == 30 /* R_AVR_DIFF8. */
15825 || reloc_type == 31 /* R_AVR_DIFF16. */
15826 || reloc_type == 32 /* R_AVR_DIFF32. */);
15827 case EM_METAG:
15828 return reloc_type == 3; /* R_METAG_NONE. */
15829 case EM_NDS32:
15830 return (reloc_type == 0 /* R_NDS32_NONE. */
15831 || reloc_type == 205 /* R_NDS32_DIFF8. */
15832 || reloc_type == 206 /* R_NDS32_DIFF16. */
15833 || reloc_type == 207 /* R_NDS32_DIFF32. */
15834 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
15835 case EM_TI_PRU:
15836 return (reloc_type == 0 /* R_PRU_NONE. */
15837 || reloc_type == 65 /* R_PRU_DIFF8. */
15838 || reloc_type == 66 /* R_PRU_DIFF16. */
15839 || reloc_type == 67 /* R_PRU_DIFF32. */);
15840 case EM_XTENSA_OLD:
15841 case EM_XTENSA:
15842 return (reloc_type == 0 /* R_XTENSA_NONE. */
15843 || reloc_type == 17 /* R_XTENSA_DIFF8. */
15844 || reloc_type == 18 /* R_XTENSA_DIFF16. */
15845 || reloc_type == 19 /* R_XTENSA_DIFF32. */
15846 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
15847 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
15848 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
15849 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
15850 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
15851 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
15853 return false;
15856 /* Returns TRUE if there is a relocation against
15857 section NAME at OFFSET bytes. */
15859 bool
15860 reloc_at (struct dwarf_section * dsec, uint64_t offset)
15862 Elf_Internal_Rela * relocs;
15863 Elf_Internal_Rela * rp;
15865 if (dsec == NULL || dsec->reloc_info == NULL)
15866 return false;
15868 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
15870 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
15871 if (rp->r_offset == offset)
15872 return true;
15874 return false;
15877 /* Apply relocations to a section.
15878 Returns TRUE upon success, FALSE otherwise.
15879 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
15880 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
15881 will be set to the number of relocs loaded.
15883 Note: So far support has been added only for those relocations
15884 which can be found in debug sections. FIXME: Add support for
15885 more relocations ? */
15887 static bool
15888 apply_relocations (Filedata *filedata,
15889 const Elf_Internal_Shdr *section,
15890 unsigned char *start,
15891 size_t size,
15892 void **relocs_return,
15893 uint64_t *num_relocs_return)
15895 Elf_Internal_Shdr * relsec;
15896 unsigned char * end = start + size;
15898 if (relocs_return != NULL)
15900 * (Elf_Internal_Rela **) relocs_return = NULL;
15901 * num_relocs_return = 0;
15904 if (filedata->file_header.e_type != ET_REL)
15905 /* No relocs to apply. */
15906 return true;
15908 /* Find the reloc section associated with the section. */
15909 for (relsec = filedata->section_headers;
15910 relsec < filedata->section_headers + filedata->file_header.e_shnum;
15911 ++relsec)
15913 bool is_rela;
15914 uint64_t num_relocs;
15915 Elf_Internal_Rela * relocs;
15916 Elf_Internal_Rela * rp;
15917 Elf_Internal_Shdr * symsec;
15918 Elf_Internal_Sym * symtab;
15919 uint64_t num_syms;
15920 Elf_Internal_Sym * sym;
15922 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
15923 || relsec->sh_info >= filedata->file_header.e_shnum
15924 || filedata->section_headers + relsec->sh_info != section
15925 || relsec->sh_size == 0
15926 || relsec->sh_link >= filedata->file_header.e_shnum)
15927 continue;
15929 symsec = filedata->section_headers + relsec->sh_link;
15930 if (symsec->sh_type != SHT_SYMTAB
15931 && symsec->sh_type != SHT_DYNSYM)
15932 return false;
15934 is_rela = relsec->sh_type == SHT_RELA;
15936 if (is_rela)
15938 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
15939 relsec->sh_size, & relocs, & num_relocs))
15940 return false;
15942 else
15944 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
15945 relsec->sh_size, & relocs, & num_relocs))
15946 return false;
15949 /* SH uses RELA but uses in place value instead of the addend field. */
15950 if (filedata->file_header.e_machine == EM_SH)
15951 is_rela = false;
15953 symtab = get_elf_symbols (filedata, symsec, & num_syms);
15955 for (rp = relocs; rp < relocs + num_relocs; ++rp)
15957 uint64_t addend;
15958 unsigned int reloc_type;
15959 unsigned int reloc_size;
15960 bool reloc_inplace = false;
15961 bool reloc_subtract = false;
15962 unsigned char *rloc;
15963 uint64_t sym_index;
15965 reloc_type = get_reloc_type (filedata, rp->r_info);
15967 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
15968 continue;
15969 else if (is_none_reloc (filedata, reloc_type))
15970 continue;
15971 else if (is_32bit_abs_reloc (filedata, reloc_type)
15972 || is_32bit_pcrel_reloc (filedata, reloc_type))
15973 reloc_size = 4;
15974 else if (is_64bit_abs_reloc (filedata, reloc_type)
15975 || is_64bit_pcrel_reloc (filedata, reloc_type))
15976 reloc_size = 8;
15977 else if (is_24bit_abs_reloc (filedata, reloc_type))
15978 reloc_size = 3;
15979 else if (is_16bit_abs_reloc (filedata, reloc_type))
15980 reloc_size = 2;
15981 else if (is_8bit_abs_reloc (filedata, reloc_type)
15982 || is_6bit_abs_reloc (filedata, reloc_type))
15983 reloc_size = 1;
15984 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
15985 reloc_type))
15986 || is_32bit_inplace_add_reloc (filedata, reloc_type))
15988 reloc_size = 4;
15989 reloc_inplace = true;
15991 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
15992 reloc_type))
15993 || is_64bit_inplace_add_reloc (filedata, reloc_type))
15995 reloc_size = 8;
15996 reloc_inplace = true;
15998 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
15999 reloc_type))
16000 || is_16bit_inplace_add_reloc (filedata, reloc_type))
16002 reloc_size = 2;
16003 reloc_inplace = true;
16005 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
16006 reloc_type))
16007 || is_8bit_inplace_add_reloc (filedata, reloc_type))
16009 reloc_size = 1;
16010 reloc_inplace = true;
16012 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
16013 reloc_type))
16014 || is_6bit_inplace_add_reloc (filedata, reloc_type))
16016 reloc_size = 1;
16017 reloc_inplace = true;
16019 else
16021 static unsigned int prev_reloc = 0;
16023 if (reloc_type != prev_reloc)
16024 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
16025 reloc_type, printable_section_name (filedata, section));
16026 prev_reloc = reloc_type;
16027 continue;
16030 rloc = start + rp->r_offset;
16031 if (!IN_RANGE (start, end, rloc, reloc_size))
16033 warn (_("skipping invalid relocation offset %#" PRIx64
16034 " in section %s\n"),
16035 rp->r_offset,
16036 printable_section_name (filedata, section));
16037 continue;
16040 sym_index = get_reloc_symindex (rp->r_info);
16041 if (sym_index >= num_syms)
16043 warn (_("skipping invalid relocation symbol index %#" PRIx64
16044 " in section %s\n"),
16045 sym_index, printable_section_name (filedata, section));
16046 continue;
16048 sym = symtab + sym_index;
16050 /* If the reloc has a symbol associated with it,
16051 make sure that it is of an appropriate type.
16053 Relocations against symbols without type can happen.
16054 Gcc -feliminate-dwarf2-dups may generate symbols
16055 without type for debug info.
16057 Icc generates relocations against function symbols
16058 instead of local labels.
16060 Relocations against object symbols can happen, eg when
16061 referencing a global array. For an example of this see
16062 the _clz.o binary in libgcc.a. */
16063 if (sym != symtab
16064 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
16065 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
16067 warn (_("skipping unexpected symbol type %s in section %s relocation %tu\n"),
16068 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
16069 printable_section_name (filedata, relsec),
16070 rp - relocs);
16071 continue;
16074 addend = 0;
16075 if (is_rela)
16076 addend += rp->r_addend;
16077 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
16078 partial_inplace. */
16079 if (!is_rela
16080 || (filedata->file_header.e_machine == EM_XTENSA
16081 && reloc_type == 1)
16082 || ((filedata->file_header.e_machine == EM_PJ
16083 || filedata->file_header.e_machine == EM_PJ_OLD)
16084 && reloc_type == 1)
16085 || ((filedata->file_header.e_machine == EM_D30V
16086 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
16087 && reloc_type == 12)
16088 || reloc_inplace)
16090 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
16091 addend += byte_get (rloc, reloc_size) & 0x3f;
16092 else
16093 addend += byte_get (rloc, reloc_size);
16096 if (is_32bit_pcrel_reloc (filedata, reloc_type)
16097 || is_64bit_pcrel_reloc (filedata, reloc_type))
16099 /* On HPPA, all pc-relative relocations are biased by 8. */
16100 if (filedata->file_header.e_machine == EM_PARISC)
16101 addend -= 8;
16102 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
16103 reloc_size);
16105 else if (is_6bit_abs_reloc (filedata, reloc_type)
16106 || is_6bit_inplace_sub_reloc (filedata, reloc_type)
16107 || is_6bit_inplace_add_reloc (filedata, reloc_type))
16109 if (reloc_subtract)
16110 addend -= sym->st_value;
16111 else
16112 addend += sym->st_value;
16113 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
16114 byte_put (rloc, addend, reloc_size);
16116 else if (reloc_subtract)
16117 byte_put (rloc, addend - sym->st_value, reloc_size);
16118 else
16119 byte_put (rloc, addend + sym->st_value, reloc_size);
16122 free (symtab);
16123 /* Let the target specific reloc processing code know that
16124 we have finished with these relocs. */
16125 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
16127 if (relocs_return)
16129 * (Elf_Internal_Rela **) relocs_return = relocs;
16130 * num_relocs_return = num_relocs;
16132 else
16133 free (relocs);
16135 break;
16138 return true;
16141 #ifdef SUPPORT_DISASSEMBLY
16142 static bool
16143 disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
16145 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
16147 /* FIXME: XXX -- to be done --- XXX */
16149 return true;
16151 #endif
16153 /* Reads in the contents of SECTION from FILE, returning a pointer
16154 to a malloc'ed buffer or NULL if something went wrong. */
16156 static char *
16157 get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
16159 uint64_t num_bytes = section->sh_size;
16161 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
16163 printf (_("Section '%s' has no data to dump.\n"),
16164 printable_section_name (filedata, section));
16165 return NULL;
16168 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
16169 _("section contents"));
16172 /* Uncompresses a section that was compressed using zlib/zstd, in place. */
16174 static bool
16175 uncompress_section_contents (bool is_zstd,
16176 unsigned char ** buffer,
16177 uint64_t uncompressed_size,
16178 uint64_t * size,
16179 uint64_t file_size)
16181 uint64_t compressed_size = *size;
16182 unsigned char *compressed_buffer = *buffer;
16183 unsigned char *uncompressed_buffer = NULL;
16184 z_stream strm;
16185 int rc;
16187 /* Similar to bfd_section_size_insane() in the BFD library we expect an
16188 upper limit of ~10x compression. Any compression larger than that is
16189 thought to be due to fuzzing of the compression header. */
16190 if (uncompressed_size > file_size * 10)
16192 error (_("Uncompressed section size is suspiciously large: 0x%" PRIu64 "\n"),
16193 uncompressed_size);
16194 goto fail;
16197 uncompressed_buffer = xmalloc (uncompressed_size);
16199 if (is_zstd)
16201 #ifdef HAVE_ZSTD
16202 size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size,
16203 compressed_buffer, compressed_size);
16204 if (ZSTD_isError (ret))
16205 goto fail;
16206 #endif
16208 else
16210 /* It is possible the section consists of several compressed
16211 buffers concatenated together, so we uncompress in a loop. */
16212 /* PR 18313: The state field in the z_stream structure is supposed
16213 to be invisible to the user (ie us), but some compilers will
16214 still complain about it being used without initialisation. So
16215 we first zero the entire z_stream structure and then set the fields
16216 that we need. */
16217 memset (&strm, 0, sizeof strm);
16218 strm.avail_in = compressed_size;
16219 strm.next_in = (Bytef *)compressed_buffer;
16220 strm.avail_out = uncompressed_size;
16222 rc = inflateInit (&strm);
16223 while (strm.avail_in > 0)
16225 if (rc != Z_OK)
16226 break;
16227 strm.next_out = ((Bytef *)uncompressed_buffer
16228 + (uncompressed_size - strm.avail_out));
16229 rc = inflate (&strm, Z_FINISH);
16230 if (rc != Z_STREAM_END)
16231 break;
16232 rc = inflateReset (&strm);
16234 if (inflateEnd (&strm) != Z_OK || rc != Z_OK || strm.avail_out != 0)
16235 goto fail;
16238 *buffer = uncompressed_buffer;
16239 *size = uncompressed_size;
16240 return true;
16242 fail:
16243 free (uncompressed_buffer);
16244 /* Indicate decompression failure. */
16245 *buffer = NULL;
16246 return false;
16249 static uint64_t
16250 maybe_expand_or_relocate_section (Elf_Internal_Shdr * section,
16251 Filedata * filedata,
16252 unsigned char ** start_ptr,
16253 bool relocate)
16255 uint64_t section_size = section->sh_size;
16256 unsigned char * start = * start_ptr;
16258 if (decompress_dumps)
16260 uint64_t new_size = section_size;
16261 uint64_t uncompressed_size = 0;
16262 bool is_zstd = false;
16264 if ((section->sh_flags & SHF_COMPRESSED) != 0)
16266 Elf_Internal_Chdr chdr;
16267 unsigned int compression_header_size
16268 = get_compression_header (& chdr, start, section_size);
16270 if (compression_header_size == 0)
16271 /* An error message will have already been generated
16272 by get_compression_header. */
16273 return (uint64_t) -1;
16275 if (chdr.ch_type == ch_compress_zlib)
16277 #ifdef HAVE_ZSTD
16278 else if (chdr.ch_type == ch_compress_zstd)
16279 is_zstd = true;
16280 #endif
16281 else
16283 warn (_("section '%s' has unsupported compress type: %d\n"),
16284 printable_section_name (filedata, section), chdr.ch_type);
16285 return (uint64_t) -1;
16288 uncompressed_size = chdr.ch_size;
16289 start += compression_header_size;
16290 new_size -= compression_header_size;
16292 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
16294 /* Read the zlib header. In this case, it should be "ZLIB"
16295 followed by the uncompressed section size, 8 bytes in
16296 big-endian order. */
16297 uncompressed_size = start[4]; uncompressed_size <<= 8;
16298 uncompressed_size += start[5]; uncompressed_size <<= 8;
16299 uncompressed_size += start[6]; uncompressed_size <<= 8;
16300 uncompressed_size += start[7]; uncompressed_size <<= 8;
16301 uncompressed_size += start[8]; uncompressed_size <<= 8;
16302 uncompressed_size += start[9]; uncompressed_size <<= 8;
16303 uncompressed_size += start[10]; uncompressed_size <<= 8;
16304 uncompressed_size += start[11];
16305 start += 12;
16306 new_size -= 12;
16309 if (uncompressed_size)
16311 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
16312 &new_size, filedata->file_size))
16313 section_size = new_size;
16314 else
16316 error (_("Unable to decompress section %s\n"),
16317 printable_section_name (filedata, section));
16318 return (uint64_t) -1;
16321 else
16322 start = * start_ptr;
16324 else if (((section->sh_flags & SHF_COMPRESSED) != 0)
16325 || (section_size > 12 && streq ((char *) start, "ZLIB")))
16327 printf (_(" NOTE: This section is compressed, but its contents have NOT been expanded for this dump.\n"));
16330 if (relocate)
16332 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
16333 return (uint64_t) -1;
16335 else
16337 Elf_Internal_Shdr *relsec;
16339 /* If the section being dumped has relocations against it the user might
16340 be expecting these relocations to have been applied. Check for this
16341 case and issue a warning message in order to avoid confusion.
16342 FIXME: Maybe we ought to have an option that dumps a section with
16343 relocs applied ? */
16344 for (relsec = filedata->section_headers;
16345 relsec < filedata->section_headers + filedata->file_header.e_shnum;
16346 ++relsec)
16348 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
16349 || relsec->sh_info >= filedata->file_header.e_shnum
16350 || filedata->section_headers + relsec->sh_info != section
16351 || relsec->sh_size == 0
16352 || relsec->sh_link >= filedata->file_header.e_shnum)
16353 continue;
16355 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
16356 break;
16360 * start_ptr = start;
16361 return section_size;
16364 static bool
16365 dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
16367 uint64_t num_bytes;
16368 unsigned char *data;
16369 unsigned char *end;
16370 unsigned char *real_start;
16371 unsigned char *start;
16372 bool some_strings_shown;
16374 real_start = start = (unsigned char *) get_section_contents (section, filedata);
16375 if (start == NULL)
16376 /* PR 21820: Do not fail if the section was empty. */
16377 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
16379 num_bytes = section->sh_size;
16381 if (filedata->is_separate)
16382 printf (_("\nString dump of section '%s' in linked file %s:\n"),
16383 printable_section_name (filedata, section),
16384 filedata->file_name);
16385 else
16386 printf (_("\nString dump of section '%s':\n"),
16387 printable_section_name (filedata, section));
16389 num_bytes = maybe_expand_or_relocate_section (section, filedata, & start, false);
16390 if (num_bytes == (uint64_t) -1)
16391 goto error_out;
16393 data = start;
16394 end = start + num_bytes;
16395 some_strings_shown = false;
16397 #ifdef HAVE_MBSTATE_T
16398 mbstate_t state;
16399 /* Initialise the multibyte conversion state. */
16400 memset (& state, 0, sizeof (state));
16401 #endif
16403 bool continuing = false;
16405 while (data < end)
16407 while (!ISPRINT (* data))
16408 if (++ data >= end)
16409 break;
16411 if (data < end)
16413 size_t maxlen = end - data;
16415 if (continuing)
16417 printf (" ");
16418 continuing = false;
16420 else
16422 printf (" [%6tx] ", data - start);
16425 if (maxlen > 0)
16427 char c = 0;
16429 while (maxlen)
16431 c = *data++;
16433 if (c == 0)
16434 break;
16436 /* PR 25543: Treat new-lines as string-ending characters. */
16437 if (c == '\n')
16439 printf ("\\n\n");
16440 if (*data != 0)
16441 continuing = true;
16442 break;
16445 /* Do not print control characters directly as they can affect terminal
16446 settings. Such characters usually appear in the names generated
16447 by the assembler for local labels. */
16448 if (ISCNTRL (c))
16450 printf ("^%c", c + 0x40);
16452 else if (ISPRINT (c))
16454 putchar (c);
16456 else
16458 size_t n;
16459 #ifdef HAVE_MBSTATE_T
16460 wchar_t w;
16461 #endif
16462 /* Let printf do the hard work of displaying multibyte characters. */
16463 printf ("%.1s", data - 1);
16464 #ifdef HAVE_MBSTATE_T
16465 /* Try to find out how many bytes made up the character that was
16466 just printed. Advance the symbol pointer past the bytes that
16467 were displayed. */
16468 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
16469 #else
16470 n = 1;
16471 #endif
16472 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
16473 data += (n - 1);
16477 if (c != '\n')
16478 putchar ('\n');
16480 else
16482 printf (_("<corrupt>\n"));
16483 data = end;
16485 some_strings_shown = true;
16489 if (! some_strings_shown)
16490 printf (_(" No strings found in this section."));
16492 free (real_start);
16494 putchar ('\n');
16495 return true;
16497 error_out:
16498 free (real_start);
16499 return false;
16502 static bool
16503 dump_section_as_bytes (Elf_Internal_Shdr *section,
16504 Filedata *filedata,
16505 bool relocate)
16507 size_t bytes;
16508 uint64_t section_size;
16509 uint64_t addr;
16510 unsigned char *data;
16511 unsigned char *real_start;
16512 unsigned char *start;
16514 real_start = start = (unsigned char *) get_section_contents (section, filedata);
16515 if (start == NULL)
16516 /* PR 21820: Do not fail if the section was empty. */
16517 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
16519 section_size = section->sh_size;
16521 if (filedata->is_separate)
16522 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
16523 printable_section_name (filedata, section),
16524 filedata->file_name);
16525 else
16526 printf (_("\nHex dump of section '%s':\n"),
16527 printable_section_name (filedata, section));
16529 section_size = maybe_expand_or_relocate_section (section, filedata, & start, relocate);
16530 if (section_size == (uint64_t) -1)
16531 goto error_out;
16533 addr = section->sh_addr;
16534 bytes = section_size;
16535 data = start;
16537 while (bytes)
16539 int j;
16540 int k;
16541 int lbytes;
16543 lbytes = (bytes > 16 ? 16 : bytes);
16545 printf (" 0x%8.8" PRIx64 " ", addr);
16547 for (j = 0; j < 16; j++)
16549 if (j < lbytes)
16550 printf ("%2.2x", data[j]);
16551 else
16552 printf (" ");
16554 if ((j & 3) == 3)
16555 printf (" ");
16558 for (j = 0; j < lbytes; j++)
16560 k = data[j];
16561 if (k >= ' ' && k < 0x7f)
16562 printf ("%c", k);
16563 else
16564 printf (".");
16567 putchar ('\n');
16569 data += lbytes;
16570 addr += lbytes;
16571 bytes -= lbytes;
16574 free (real_start);
16576 putchar ('\n');
16577 return true;
16579 error_out:
16580 free (real_start);
16581 return false;
16584 #ifdef ENABLE_LIBCTF
16585 static ctf_sect_t *
16586 shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
16588 buf->cts_name = printable_section_name (filedata, shdr);
16589 buf->cts_size = shdr->sh_size;
16590 buf->cts_entsize = shdr->sh_entsize;
16592 return buf;
16595 /* Formatting callback function passed to ctf_dump. Returns either the pointer
16596 it is passed, or a pointer to newly-allocated storage, in which case
16597 dump_ctf() will free it when it no longer needs it. */
16599 static char *
16600 dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
16601 char *s, void *arg)
16603 const char *blanks = arg;
16604 char *new_s;
16606 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
16607 return s;
16608 return new_s;
16611 /* Dump CTF errors/warnings. */
16612 static void
16613 dump_ctf_errs (ctf_dict_t *fp)
16615 ctf_next_t *it = NULL;
16616 char *errtext;
16617 int is_warning;
16618 int err;
16620 /* Dump accumulated errors and warnings. */
16621 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
16623 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
16624 errtext);
16625 free (errtext);
16627 if (err != ECTF_NEXT_END)
16628 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
16631 /* Dump one CTF archive member. */
16633 static void
16634 dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
16635 size_t member)
16637 const char *things[] = {"Header", "Labels", "Data objects",
16638 "Function objects", "Variables", "Types", "Strings",
16639 ""};
16640 const char **thing;
16641 size_t i;
16643 /* Don't print out the name of the default-named archive member if it appears
16644 first in the list. The name .ctf appears everywhere, even for things that
16645 aren't really archives, so printing it out is liable to be confusing; also,
16646 the common case by far is for only one archive member to exist, and hiding
16647 it in that case seems worthwhile. */
16649 if (strcmp (name, ".ctf") != 0 || member != 0)
16650 printf (_("\nCTF archive member: %s:\n"), name);
16652 if (ctf_parent_name (ctf) != NULL)
16653 ctf_import (ctf, parent);
16655 for (i = 0, thing = things; *thing[0]; thing++, i++)
16657 ctf_dump_state_t *s = NULL;
16658 char *item;
16660 printf ("\n %s:\n", *thing);
16661 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
16662 (void *) " ")) != NULL)
16664 printf ("%s\n", item);
16665 free (item);
16668 if (ctf_errno (ctf))
16670 error (_("Iteration failed: %s, %s\n"), *thing,
16671 ctf_errmsg (ctf_errno (ctf)));
16672 break;
16676 dump_ctf_errs (ctf);
16679 static bool
16680 dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
16682 Elf_Internal_Shdr * symtab_sec = NULL;
16683 Elf_Internal_Shdr * strtab_sec = NULL;
16684 void * data = NULL;
16685 void * symdata = NULL;
16686 void * strdata = NULL;
16687 ctf_sect_t ctfsect, symsect, strsect;
16688 ctf_sect_t * symsectp = NULL;
16689 ctf_sect_t * strsectp = NULL;
16690 ctf_archive_t * ctfa = NULL;
16691 ctf_dict_t * parent = NULL;
16692 ctf_dict_t * fp;
16694 ctf_next_t *i = NULL;
16695 const char *name;
16696 size_t member = 0;
16697 int err;
16698 bool ret = false;
16700 shdr_to_ctf_sect (&ctfsect, section, filedata);
16701 data = get_section_contents (section, filedata);
16702 ctfsect.cts_data = data;
16704 if (!dump_ctf_symtab_name)
16705 dump_ctf_symtab_name = strdup (".dynsym");
16707 if (!dump_ctf_strtab_name)
16708 dump_ctf_strtab_name = strdup (".dynstr");
16710 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
16712 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
16714 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
16715 goto fail;
16717 if ((symdata = (void *) get_data (NULL, filedata,
16718 symtab_sec->sh_offset, 1,
16719 symtab_sec->sh_size,
16720 _("symbols"))) == NULL)
16721 goto fail;
16722 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
16723 symsect.cts_data = symdata;
16726 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
16728 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
16730 error (_("No string table section named %s\n"),
16731 dump_ctf_strtab_name);
16732 goto fail;
16734 if ((strdata = (void *) get_data (NULL, filedata,
16735 strtab_sec->sh_offset, 1,
16736 strtab_sec->sh_size,
16737 _("strings"))) == NULL)
16738 goto fail;
16739 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
16740 strsect.cts_data = strdata;
16743 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
16744 libctf papers over the difference, so we can pretend it is always an
16745 archive. */
16747 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
16749 dump_ctf_errs (NULL);
16750 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16751 goto fail;
16754 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
16755 != ELFDATA2MSB);
16757 /* Preload the parent dict, since it will need to be imported into every
16758 child in turn. */
16759 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
16761 dump_ctf_errs (NULL);
16762 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16763 goto fail;
16766 ret = true;
16768 if (filedata->is_separate)
16769 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
16770 printable_section_name (filedata, section),
16771 filedata->file_name);
16772 else
16773 printf (_("\nDump of CTF section '%s':\n"),
16774 printable_section_name (filedata, section));
16776 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
16777 dump_ctf_archive_member (fp, name, parent, member++);
16778 if (err != ECTF_NEXT_END)
16780 dump_ctf_errs (NULL);
16781 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
16782 ret = false;
16785 fail:
16786 ctf_dict_close (parent);
16787 ctf_close (ctfa);
16788 free (data);
16789 free (symdata);
16790 free (strdata);
16791 return ret;
16793 #endif
16795 static bool
16796 dump_section_as_sframe (Elf_Internal_Shdr * section, Filedata * filedata)
16798 void * data = NULL;
16799 sframe_decoder_ctx *sfd_ctx = NULL;
16800 const char *print_name = printable_section_name (filedata, section);
16802 bool ret = true;
16803 size_t sf_size;
16804 int err = 0;
16806 if (strcmp (print_name, "") == 0)
16808 error (_("Section name must be provided \n"));
16809 ret = false;
16810 return ret;
16813 data = get_section_contents (section, filedata);
16814 sf_size = section->sh_size;
16815 /* Decode the contents of the section. */
16816 sfd_ctx = sframe_decode ((const char*)data, sf_size, &err);
16817 if (!sfd_ctx)
16819 ret = false;
16820 error (_("SFrame decode failure: %s\n"), sframe_errmsg (err));
16821 goto fail;
16824 printf (_("Contents of the SFrame section %s:"), print_name);
16825 /* Dump the contents as text. */
16826 dump_sframe (sfd_ctx, section->sh_addr);
16828 fail:
16829 free (data);
16830 return ret;
16833 static bool
16834 load_specific_debug_section (enum dwarf_section_display_enum debug,
16835 const Elf_Internal_Shdr * sec,
16836 void * data)
16838 struct dwarf_section * section = &debug_displays [debug].section;
16839 char buf [64];
16840 Filedata * filedata = (Filedata *) data;
16842 if (section->start != NULL)
16844 /* If it is already loaded, do nothing. */
16845 if (streq (section->filename, filedata->file_name))
16846 return true;
16847 free (section->start);
16850 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
16851 section->address = sec->sh_addr;
16852 section->filename = filedata->file_name;
16853 section->start = (unsigned char *) get_data (NULL, filedata,
16854 sec->sh_offset, 1,
16855 sec->sh_size, buf);
16856 if (section->start == NULL)
16857 section->size = 0;
16858 else
16860 unsigned char *start = section->start;
16861 uint64_t size = sec->sh_size;
16862 uint64_t uncompressed_size = 0;
16863 bool is_zstd = false;
16865 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
16867 Elf_Internal_Chdr chdr;
16868 unsigned int compression_header_size;
16870 if (size < (is_32bit_elf
16871 ? sizeof (Elf32_External_Chdr)
16872 : sizeof (Elf64_External_Chdr)))
16874 warn (_("compressed section %s is too small to contain a compression header\n"),
16875 section->name);
16876 return false;
16879 compression_header_size = get_compression_header (&chdr, start, size);
16880 if (compression_header_size == 0)
16881 /* An error message will have already been generated
16882 by get_compression_header. */
16883 return false;
16885 if (chdr.ch_type == ch_compress_zlib)
16887 #ifdef HAVE_ZSTD
16888 else if (chdr.ch_type == ch_compress_zstd)
16889 is_zstd = true;
16890 #endif
16891 else
16893 warn (_("section '%s' has unsupported compress type: %d\n"),
16894 section->name, chdr.ch_type);
16895 return false;
16897 uncompressed_size = chdr.ch_size;
16898 start += compression_header_size;
16899 size -= compression_header_size;
16901 else if (size > 12 && streq ((char *) start, "ZLIB"))
16903 /* Read the zlib header. In this case, it should be "ZLIB"
16904 followed by the uncompressed section size, 8 bytes in
16905 big-endian order. */
16906 uncompressed_size = start[4]; uncompressed_size <<= 8;
16907 uncompressed_size += start[5]; uncompressed_size <<= 8;
16908 uncompressed_size += start[6]; uncompressed_size <<= 8;
16909 uncompressed_size += start[7]; uncompressed_size <<= 8;
16910 uncompressed_size += start[8]; uncompressed_size <<= 8;
16911 uncompressed_size += start[9]; uncompressed_size <<= 8;
16912 uncompressed_size += start[10]; uncompressed_size <<= 8;
16913 uncompressed_size += start[11];
16914 start += 12;
16915 size -= 12;
16918 if (uncompressed_size)
16920 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
16921 &size, filedata->file_size))
16923 /* Free the compressed buffer, update the section buffer
16924 and the section size if uncompress is successful. */
16925 free (section->start);
16926 section->start = start;
16928 else
16930 error (_("Unable to decompress section %s\n"),
16931 printable_section_name (filedata, sec));
16932 return false;
16936 section->size = size;
16939 if (section->start == NULL)
16940 return false;
16942 if (debug_displays [debug].relocate)
16944 if (! apply_relocations (filedata, sec, section->start, section->size,
16945 & section->reloc_info, & section->num_relocs))
16946 return false;
16948 else
16950 section->reloc_info = NULL;
16951 section->num_relocs = 0;
16954 return true;
16957 #if HAVE_LIBDEBUGINFOD
16958 /* Return a hex string representation of the build-id. */
16959 unsigned char *
16960 get_build_id (void * data)
16962 Filedata * filedata = (Filedata *) data;
16963 Elf_Internal_Shdr * shdr;
16964 size_t i;
16966 /* Iterate through notes to find note.gnu.build-id.
16967 FIXME: Only the first note in any note section is examined. */
16968 for (i = 0, shdr = filedata->section_headers;
16969 i < filedata->file_header.e_shnum && shdr != NULL;
16970 i++, shdr++)
16972 if (shdr->sh_type != SHT_NOTE)
16973 continue;
16975 char * next;
16976 char * end;
16977 size_t data_remaining;
16978 size_t min_notesz;
16979 Elf_External_Note * enote;
16980 Elf_Internal_Note inote;
16982 uint64_t offset = shdr->sh_offset;
16983 uint64_t align = shdr->sh_addralign;
16984 uint64_t length = shdr->sh_size;
16986 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
16987 if (enote == NULL)
16988 continue;
16990 if (align < 4)
16991 align = 4;
16992 else if (align != 4 && align != 8)
16994 free (enote);
16995 continue;
16998 end = (char *) enote + length;
16999 data_remaining = end - (char *) enote;
17001 if (!is_ia64_vms (filedata))
17003 min_notesz = offsetof (Elf_External_Note, name);
17004 if (data_remaining < min_notesz)
17006 warn (_("\
17007 malformed note encountered in section %s whilst scanning for build-id note\n"),
17008 printable_section_name (filedata, shdr));
17009 free (enote);
17010 continue;
17012 data_remaining -= min_notesz;
17014 inote.type = BYTE_GET (enote->type);
17015 inote.namesz = BYTE_GET (enote->namesz);
17016 inote.namedata = enote->name;
17017 inote.descsz = BYTE_GET (enote->descsz);
17018 inote.descdata = ((char *) enote
17019 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
17020 inote.descpos = offset + (inote.descdata - (char *) enote);
17021 next = ((char *) enote
17022 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
17024 else
17026 Elf64_External_VMS_Note *vms_enote;
17028 /* PR binutils/15191
17029 Make sure that there is enough data to read. */
17030 min_notesz = offsetof (Elf64_External_VMS_Note, name);
17031 if (data_remaining < min_notesz)
17033 warn (_("\
17034 malformed note encountered in section %s whilst scanning for build-id note\n"),
17035 printable_section_name (filedata, shdr));
17036 free (enote);
17037 continue;
17039 data_remaining -= min_notesz;
17041 vms_enote = (Elf64_External_VMS_Note *) enote;
17042 inote.type = BYTE_GET (vms_enote->type);
17043 inote.namesz = BYTE_GET (vms_enote->namesz);
17044 inote.namedata = vms_enote->name;
17045 inote.descsz = BYTE_GET (vms_enote->descsz);
17046 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
17047 inote.descpos = offset + (inote.descdata - (char *) enote);
17048 next = inote.descdata + align_power (inote.descsz, 3);
17051 /* Skip malformed notes. */
17052 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
17053 || (size_t) (inote.descdata - inote.namedata) > data_remaining
17054 || (size_t) (next - inote.descdata) < inote.descsz
17055 || ((size_t) (next - inote.descdata)
17056 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
17058 warn (_("\
17059 malformed note encountered in section %s whilst scanning for build-id note\n"),
17060 printable_section_name (filedata, shdr));
17061 free (enote);
17062 continue;
17065 /* Check if this is the build-id note. If so then convert the build-id
17066 bytes to a hex string. */
17067 if (inote.namesz > 0
17068 && startswith (inote.namedata, "GNU")
17069 && inote.type == NT_GNU_BUILD_ID)
17071 size_t j;
17072 char * build_id;
17074 build_id = malloc (inote.descsz * 2 + 1);
17075 if (build_id == NULL)
17077 free (enote);
17078 return NULL;
17081 for (j = 0; j < inote.descsz; ++j)
17082 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
17083 build_id[inote.descsz * 2] = '\0';
17084 free (enote);
17086 return (unsigned char *) build_id;
17088 free (enote);
17091 return NULL;
17093 #endif /* HAVE_LIBDEBUGINFOD */
17095 /* If this is not NULL, load_debug_section will only look for sections
17096 within the list of sections given here. */
17097 static unsigned int * section_subset = NULL;
17099 bool
17100 load_debug_section (enum dwarf_section_display_enum debug, void * data)
17102 struct dwarf_section * section = &debug_displays [debug].section;
17103 Elf_Internal_Shdr * sec;
17104 Filedata * filedata = (Filedata *) data;
17106 if (!dump_any_debugging)
17107 return false;
17109 /* Without section headers we cannot find any sections. */
17110 if (filedata->section_headers == NULL)
17111 return false;
17113 if (filedata->string_table == NULL
17114 && filedata->file_header.e_shstrndx != SHN_UNDEF
17115 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
17117 Elf_Internal_Shdr * strs;
17119 /* Read in the string table, so that we have section names to scan. */
17120 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
17122 if (strs != NULL && strs->sh_size != 0)
17124 filedata->string_table
17125 = (char *) get_data (NULL, filedata, strs->sh_offset,
17126 1, strs->sh_size, _("string table"));
17128 filedata->string_table_length
17129 = filedata->string_table != NULL ? strs->sh_size : 0;
17133 /* Locate the debug section. */
17134 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
17135 if (sec != NULL)
17136 section->name = section->uncompressed_name;
17137 else
17139 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
17140 if (sec != NULL)
17141 section->name = section->compressed_name;
17143 if (sec == NULL)
17144 return false;
17146 /* If we're loading from a subset of sections, and we've loaded
17147 a section matching this name before, it's likely that it's a
17148 different one. */
17149 if (section_subset != NULL)
17150 free_debug_section (debug);
17152 return load_specific_debug_section (debug, sec, data);
17155 void
17156 free_debug_section (enum dwarf_section_display_enum debug)
17158 struct dwarf_section * section = &debug_displays [debug].section;
17160 if (section->start == NULL)
17161 return;
17163 free ((char *) section->start);
17164 section->start = NULL;
17165 section->address = 0;
17166 section->size = 0;
17168 free (section->reloc_info);
17169 section->reloc_info = NULL;
17170 section->num_relocs = 0;
17173 static bool
17174 display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
17176 const char *name = (section_name_valid (filedata, section)
17177 ? section_name (filedata, section) : "");
17178 const char *print_name = printable_section_name (filedata, section);
17179 uint64_t length;
17180 bool result = true;
17181 int i;
17183 length = section->sh_size;
17184 if (length == 0)
17186 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
17187 return true;
17189 if (section->sh_type == SHT_NOBITS)
17191 /* There is no point in dumping the contents of a debugging section
17192 which has the NOBITS type - the bits in the file will be random.
17193 This can happen when a file containing a .eh_frame section is
17194 stripped with the --only-keep-debug command line option. */
17195 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
17196 print_name);
17197 return false;
17200 if (startswith (name, ".gnu.linkonce.wi."))
17201 name = ".debug_info";
17203 /* See if we know how to display the contents of this section. */
17204 for (i = 0; i < max; i++)
17206 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
17207 struct dwarf_section_display * display = debug_displays + i;
17208 struct dwarf_section * sec = & display->section;
17210 if (streq (sec->uncompressed_name, name)
17211 || (id == line && startswith (name, ".debug_line."))
17212 || streq (sec->compressed_name, name))
17214 bool secondary = (section != find_section (filedata, name));
17216 if (secondary)
17217 free_debug_section (id);
17219 if (i == line && startswith (name, ".debug_line."))
17220 sec->name = name;
17221 else if (streq (sec->uncompressed_name, name))
17222 sec->name = sec->uncompressed_name;
17223 else
17224 sec->name = sec->compressed_name;
17226 if (load_specific_debug_section (id, section, filedata))
17228 /* If this debug section is part of a CU/TU set in a .dwp file,
17229 restrict load_debug_section to the sections in that set. */
17230 section_subset = find_cu_tu_set (filedata, shndx);
17232 result &= display->display (sec, filedata);
17234 section_subset = NULL;
17236 if (secondary || (id != info && id != abbrev && id != debug_addr))
17237 free_debug_section (id);
17239 break;
17243 if (i == max)
17245 printf (_("Unrecognized debug section: %s\n"), print_name);
17246 result = false;
17249 return result;
17252 /* Set DUMP_SECTS for all sections where dumps were requested
17253 based on section name. */
17255 static void
17256 initialise_dumps_byname (Filedata * filedata)
17258 struct dump_list_entry * cur;
17260 for (cur = dump_sects_byname; cur; cur = cur->next)
17262 unsigned int i;
17263 bool any = false;
17265 for (i = 0; i < filedata->file_header.e_shnum; i++)
17266 if (section_name_valid (filedata, filedata->section_headers + i)
17267 && streq (section_name (filedata, filedata->section_headers + i),
17268 cur->name))
17270 request_dump_bynumber (&filedata->dump, i, cur->type);
17271 any = true;
17274 if (!any && !filedata->is_separate)
17275 warn (_("Section '%s' was not dumped because it does not exist\n"),
17276 cur->name);
17280 static bool
17281 process_section_contents (Filedata * filedata)
17283 Elf_Internal_Shdr * section;
17284 unsigned int i;
17285 bool res = true;
17287 if (! do_dump)
17288 return true;
17290 initialise_dumps_byname (filedata);
17292 for (i = 0, section = filedata->section_headers;
17293 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
17294 i++, section++)
17296 dump_type dump = filedata->dump.dump_sects[i];
17298 if (filedata->is_separate && ! process_links)
17299 dump &= DEBUG_DUMP;
17301 if (dump & AUTO_DUMP)
17303 switch (section->sh_type)
17305 case SHT_PROGBITS:
17306 /* FIXME: There are lots of different type of section that have
17307 SHT_PROGBITS set in their header - code, debug info, etc. So
17308 we should check the section's name and interpret its contents
17309 that way, rather than just defaulting to a byte dump. */
17310 #ifdef SUPPORT_DISASSEMBLY
17311 res &= disassemble_section (section, filedata);
17312 #else
17313 res &= dump_section_as_bytes (section, filedata, false);
17314 #endif
17315 break;
17317 case SHT_DYNSYM:
17318 case SHT_SYMTAB:
17319 res &= dump_symbol_section (section, filedata);
17320 break;
17322 case SHT_STRTAB:
17323 res &= dump_section_as_strings (section, filedata);
17324 break;
17326 case SHT_RELA:
17327 case SHT_REL:
17328 case SHT_RELR:
17329 res &= display_relocations (section, filedata);
17330 break;
17332 case SHT_NOTE:
17333 res &= process_notes_at (filedata, section, section->sh_offset,
17334 section->sh_size, section->sh_addralign);
17335 break;
17337 case SHT_NULL:
17338 inform (_("Unable to display section %d - it has a NULL type\n"), i);
17339 break;
17341 case SHT_NOBITS:
17342 inform (_("Unable to display section %d - it has no contents\n"), i);
17343 break;
17345 case SHT_HASH:
17346 case SHT_DYNAMIC:
17347 case SHT_GROUP:
17348 case SHT_GNU_ATTRIBUTES:
17349 /* FIXME: Implement these. */
17350 /* Fall through. */
17351 default:
17352 /* FIXME: Add Proc and OS specific section types ? */
17353 warn (_("Unable to determine how to dump section %d (type %#x)\n"),
17354 i, section->sh_type);
17355 res = false;
17356 break;
17360 #ifdef SUPPORT_DISASSEMBLY
17361 if (dump & DISASS_DUMP)
17363 if (! disassemble_section (section, filedata))
17364 res = false;
17366 #endif
17367 if (dump & HEX_DUMP)
17369 if (! dump_section_as_bytes (section, filedata, false))
17370 res = false;
17373 if (dump & RELOC_DUMP)
17375 if (! dump_section_as_bytes (section, filedata, true))
17376 res = false;
17379 if (dump & STRING_DUMP)
17381 if (! dump_section_as_strings (section, filedata))
17382 res = false;
17385 if (dump & DEBUG_DUMP)
17387 if (! display_debug_section (i, section, filedata))
17388 res = false;
17391 #ifdef ENABLE_LIBCTF
17392 if (dump & CTF_DUMP)
17394 if (! dump_section_as_ctf (section, filedata))
17395 res = false;
17397 #endif
17398 if (dump & SFRAME_DUMP)
17400 if (! dump_section_as_sframe (section, filedata))
17401 res = false;
17405 if (! filedata->is_separate)
17407 /* Check to see if the user requested a
17408 dump of a section that does not exist. */
17409 for (; i < filedata->dump.num_dump_sects; i++)
17410 if (filedata->dump.dump_sects[i])
17412 warn (_("Section %d was not dumped because it does not exist!\n"), i);
17413 res = false;
17417 return res;
17420 static void
17421 process_mips_fpe_exception (int mask)
17423 if (mask)
17425 bool first = true;
17427 if (mask & OEX_FPU_INEX)
17428 fputs ("INEX", stdout), first = false;
17429 if (mask & OEX_FPU_UFLO)
17430 printf ("%sUFLO", first ? "" : "|"), first = false;
17431 if (mask & OEX_FPU_OFLO)
17432 printf ("%sOFLO", first ? "" : "|"), first = false;
17433 if (mask & OEX_FPU_DIV0)
17434 printf ("%sDIV0", first ? "" : "|"), first = false;
17435 if (mask & OEX_FPU_INVAL)
17436 printf ("%sINVAL", first ? "" : "|");
17438 else
17439 fputs ("0", stdout);
17442 /* Display's the value of TAG at location P. If TAG is
17443 greater than 0 it is assumed to be an unknown tag, and
17444 a message is printed to this effect. Otherwise it is
17445 assumed that a message has already been printed.
17447 If the bottom bit of TAG is set it assumed to have a
17448 string value, otherwise it is assumed to have an integer
17449 value.
17451 Returns an updated P pointing to the first unread byte
17452 beyond the end of TAG's value.
17454 Reads at or beyond END will not be made. */
17456 static unsigned char *
17457 display_tag_value (signed int tag,
17458 unsigned char * p,
17459 const unsigned char * const end)
17461 uint64_t val;
17463 if (tag > 0)
17464 printf (" Tag_unknown_%d: ", tag);
17466 if (p >= end)
17468 warn (_("<corrupt tag>\n"));
17470 else if (tag & 1)
17472 /* PR 17531 file: 027-19978-0.004. */
17473 size_t maxlen = (end - p) - 1;
17475 putchar ('"');
17476 if (maxlen > 0)
17478 print_symbol_name ((int) maxlen, (const char *) p);
17479 p += strnlen ((char *) p, maxlen) + 1;
17481 else
17483 printf (_("<corrupt string tag>"));
17484 p = (unsigned char *) end;
17486 printf ("\"\n");
17488 else
17490 READ_ULEB (val, p, end);
17491 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
17494 assert (p <= end);
17495 return p;
17498 /* ARC ABI attributes section. */
17500 static unsigned char *
17501 display_arc_attribute (unsigned char * p,
17502 const unsigned char * const end)
17504 unsigned int tag;
17505 unsigned int val;
17507 READ_ULEB (tag, p, end);
17509 switch (tag)
17511 case Tag_ARC_PCS_config:
17512 READ_ULEB (val, p, end);
17513 printf (" Tag_ARC_PCS_config: ");
17514 switch (val)
17516 case 0:
17517 printf (_("Absent/Non standard\n"));
17518 break;
17519 case 1:
17520 printf (_("Bare metal/mwdt\n"));
17521 break;
17522 case 2:
17523 printf (_("Bare metal/newlib\n"));
17524 break;
17525 case 3:
17526 printf (_("Linux/uclibc\n"));
17527 break;
17528 case 4:
17529 printf (_("Linux/glibc\n"));
17530 break;
17531 default:
17532 printf (_("Unknown\n"));
17533 break;
17535 break;
17537 case Tag_ARC_CPU_base:
17538 READ_ULEB (val, p, end);
17539 printf (" Tag_ARC_CPU_base: ");
17540 switch (val)
17542 default:
17543 case TAG_CPU_NONE:
17544 printf (_("Absent\n"));
17545 break;
17546 case TAG_CPU_ARC6xx:
17547 printf ("ARC6xx\n");
17548 break;
17549 case TAG_CPU_ARC7xx:
17550 printf ("ARC7xx\n");
17551 break;
17552 case TAG_CPU_ARCEM:
17553 printf ("ARCEM\n");
17554 break;
17555 case TAG_CPU_ARCHS:
17556 printf ("ARCHS\n");
17557 break;
17559 break;
17561 case Tag_ARC_CPU_variation:
17562 READ_ULEB (val, p, end);
17563 printf (" Tag_ARC_CPU_variation: ");
17564 switch (val)
17566 default:
17567 if (val > 0 && val < 16)
17568 printf ("Core%d\n", val);
17569 else
17570 printf ("Unknown\n");
17571 break;
17573 case 0:
17574 printf (_("Absent\n"));
17575 break;
17577 break;
17579 case Tag_ARC_CPU_name:
17580 printf (" Tag_ARC_CPU_name: ");
17581 p = display_tag_value (-1, p, end);
17582 break;
17584 case Tag_ARC_ABI_rf16:
17585 READ_ULEB (val, p, end);
17586 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
17587 break;
17589 case Tag_ARC_ABI_osver:
17590 READ_ULEB (val, p, end);
17591 printf (" Tag_ARC_ABI_osver: v%d\n", val);
17592 break;
17594 case Tag_ARC_ABI_pic:
17595 case Tag_ARC_ABI_sda:
17596 READ_ULEB (val, p, end);
17597 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
17598 : " Tag_ARC_ABI_pic: ");
17599 switch (val)
17601 case 0:
17602 printf (_("Absent\n"));
17603 break;
17604 case 1:
17605 printf ("MWDT\n");
17606 break;
17607 case 2:
17608 printf ("GNU\n");
17609 break;
17610 default:
17611 printf (_("Unknown\n"));
17612 break;
17614 break;
17616 case Tag_ARC_ABI_tls:
17617 READ_ULEB (val, p, end);
17618 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
17619 break;
17621 case Tag_ARC_ABI_enumsize:
17622 READ_ULEB (val, p, end);
17623 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
17624 _("smallest"));
17625 break;
17627 case Tag_ARC_ABI_exceptions:
17628 READ_ULEB (val, p, end);
17629 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
17630 : _("default"));
17631 break;
17633 case Tag_ARC_ABI_double_size:
17634 READ_ULEB (val, p, end);
17635 printf (" Tag_ARC_ABI_double_size: %d\n", val);
17636 break;
17638 case Tag_ARC_ISA_config:
17639 printf (" Tag_ARC_ISA_config: ");
17640 p = display_tag_value (-1, p, end);
17641 break;
17643 case Tag_ARC_ISA_apex:
17644 printf (" Tag_ARC_ISA_apex: ");
17645 p = display_tag_value (-1, p, end);
17646 break;
17648 case Tag_ARC_ISA_mpy_option:
17649 READ_ULEB (val, p, end);
17650 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
17651 break;
17653 case Tag_ARC_ATR_version:
17654 READ_ULEB (val, p, end);
17655 printf (" Tag_ARC_ATR_version: %d\n", val);
17656 break;
17658 default:
17659 return display_tag_value (tag & 1, p, end);
17662 return p;
17665 /* ARM EABI attributes section. */
17666 typedef struct
17668 unsigned int tag;
17669 const char * name;
17670 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
17671 unsigned int type;
17672 const char *const *table;
17673 } arm_attr_public_tag;
17675 static const char *const arm_attr_tag_CPU_arch[] =
17676 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
17677 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
17678 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
17679 "v8.1-M.mainline", "v9"};
17680 static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
17681 static const char *const arm_attr_tag_THUMB_ISA_use[] =
17682 {"No", "Thumb-1", "Thumb-2", "Yes"};
17683 static const char *const arm_attr_tag_FP_arch[] =
17684 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
17685 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
17686 static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
17687 static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
17688 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
17689 "NEON for ARMv8.1"};
17690 static const char *const arm_attr_tag_PCS_config[] =
17691 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
17692 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
17693 static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
17694 {"V6", "SB", "TLS", "Unused"};
17695 static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
17696 {"Absolute", "PC-relative", "SB-relative", "None"};
17697 static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
17698 {"Absolute", "PC-relative", "None"};
17699 static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
17700 {"None", "direct", "GOT-indirect"};
17701 static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
17702 {"None", "??? 1", "2", "??? 3", "4"};
17703 static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
17704 static const char *const arm_attr_tag_ABI_FP_denormal[] =
17705 {"Unused", "Needed", "Sign only"};
17706 static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
17707 static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
17708 static const char *const arm_attr_tag_ABI_FP_number_model[] =
17709 {"Unused", "Finite", "RTABI", "IEEE 754"};
17710 static const char *const arm_attr_tag_ABI_enum_size[] =
17711 {"Unused", "small", "int", "forced to int"};
17712 static const char *const arm_attr_tag_ABI_HardFP_use[] =
17713 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
17714 static const char *const arm_attr_tag_ABI_VFP_args[] =
17715 {"AAPCS", "VFP registers", "custom", "compatible"};
17716 static const char *const arm_attr_tag_ABI_WMMX_args[] =
17717 {"AAPCS", "WMMX registers", "custom"};
17718 static const char *const arm_attr_tag_ABI_optimization_goals[] =
17719 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
17720 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
17721 static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
17722 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
17723 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
17724 static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
17725 static const char *const arm_attr_tag_FP_HP_extension[] =
17726 {"Not Allowed", "Allowed"};
17727 static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
17728 {"None", "IEEE 754", "Alternative Format"};
17729 static const char *const arm_attr_tag_DSP_extension[] =
17730 {"Follow architecture", "Allowed"};
17731 static const char *const arm_attr_tag_MPextension_use[] =
17732 {"Not Allowed", "Allowed"};
17733 static const char *const arm_attr_tag_DIV_use[] =
17734 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
17735 "Allowed in v7-A with integer division extension"};
17736 static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
17737 static const char *const arm_attr_tag_Virtualization_use[] =
17738 {"Not Allowed", "TrustZone", "Virtualization Extensions",
17739 "TrustZone and Virtualization Extensions"};
17740 static const char *const arm_attr_tag_MPextension_use_legacy[] =
17741 {"Not Allowed", "Allowed"};
17743 static const char *const arm_attr_tag_MVE_arch[] =
17744 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
17746 static const char * arm_attr_tag_PAC_extension[] =
17747 {"No PAC/AUT instructions",
17748 "PAC/AUT instructions permitted in the NOP space",
17749 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
17751 static const char * arm_attr_tag_BTI_extension[] =
17752 {"BTI instructions not permitted",
17753 "BTI instructions permitted in the NOP space",
17754 "BTI instructions permitted in the NOP and in the non-NOP space"};
17756 static const char * arm_attr_tag_BTI_use[] =
17757 {"Compiled without branch target enforcement",
17758 "Compiled with branch target enforcement"};
17760 static const char * arm_attr_tag_PACRET_use[] =
17761 {"Compiled without return address signing and authentication",
17762 "Compiled with return address signing and authentication"};
17764 #define LOOKUP(id, name) \
17765 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
17766 static arm_attr_public_tag arm_attr_public_tags[] =
17768 {4, "CPU_raw_name", 1, NULL},
17769 {5, "CPU_name", 1, NULL},
17770 LOOKUP(6, CPU_arch),
17771 {7, "CPU_arch_profile", 0, NULL},
17772 LOOKUP(8, ARM_ISA_use),
17773 LOOKUP(9, THUMB_ISA_use),
17774 LOOKUP(10, FP_arch),
17775 LOOKUP(11, WMMX_arch),
17776 LOOKUP(12, Advanced_SIMD_arch),
17777 LOOKUP(13, PCS_config),
17778 LOOKUP(14, ABI_PCS_R9_use),
17779 LOOKUP(15, ABI_PCS_RW_data),
17780 LOOKUP(16, ABI_PCS_RO_data),
17781 LOOKUP(17, ABI_PCS_GOT_use),
17782 LOOKUP(18, ABI_PCS_wchar_t),
17783 LOOKUP(19, ABI_FP_rounding),
17784 LOOKUP(20, ABI_FP_denormal),
17785 LOOKUP(21, ABI_FP_exceptions),
17786 LOOKUP(22, ABI_FP_user_exceptions),
17787 LOOKUP(23, ABI_FP_number_model),
17788 {24, "ABI_align_needed", 0, NULL},
17789 {25, "ABI_align_preserved", 0, NULL},
17790 LOOKUP(26, ABI_enum_size),
17791 LOOKUP(27, ABI_HardFP_use),
17792 LOOKUP(28, ABI_VFP_args),
17793 LOOKUP(29, ABI_WMMX_args),
17794 LOOKUP(30, ABI_optimization_goals),
17795 LOOKUP(31, ABI_FP_optimization_goals),
17796 {32, "compatibility", 0, NULL},
17797 LOOKUP(34, CPU_unaligned_access),
17798 LOOKUP(36, FP_HP_extension),
17799 LOOKUP(38, ABI_FP_16bit_format),
17800 LOOKUP(42, MPextension_use),
17801 LOOKUP(44, DIV_use),
17802 LOOKUP(46, DSP_extension),
17803 LOOKUP(48, MVE_arch),
17804 LOOKUP(50, PAC_extension),
17805 LOOKUP(52, BTI_extension),
17806 LOOKUP(74, BTI_use),
17807 LOOKUP(76, PACRET_use),
17808 {64, "nodefaults", 0, NULL},
17809 {65, "also_compatible_with", 0, NULL},
17810 LOOKUP(66, T2EE_use),
17811 {67, "conformance", 1, NULL},
17812 LOOKUP(68, Virtualization_use),
17813 LOOKUP(70, MPextension_use_legacy)
17815 #undef LOOKUP
17817 static unsigned char *
17818 display_arm_attribute (unsigned char * p,
17819 const unsigned char * const end)
17821 unsigned int tag;
17822 unsigned int val;
17823 arm_attr_public_tag * attr;
17824 unsigned i;
17825 unsigned int type;
17827 READ_ULEB (tag, p, end);
17828 attr = NULL;
17829 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
17831 if (arm_attr_public_tags[i].tag == tag)
17833 attr = &arm_attr_public_tags[i];
17834 break;
17838 if (attr)
17840 printf (" Tag_%s: ", attr->name);
17841 switch (attr->type)
17843 case 0:
17844 switch (tag)
17846 case 7: /* Tag_CPU_arch_profile. */
17847 READ_ULEB (val, p, end);
17848 switch (val)
17850 case 0: printf (_("None\n")); break;
17851 case 'A': printf (_("Application\n")); break;
17852 case 'R': printf (_("Realtime\n")); break;
17853 case 'M': printf (_("Microcontroller\n")); break;
17854 case 'S': printf (_("Application or Realtime\n")); break;
17855 default: printf ("??? (%d)\n", val); break;
17857 break;
17859 case 24: /* Tag_align_needed. */
17860 READ_ULEB (val, p, end);
17861 switch (val)
17863 case 0: printf (_("None\n")); break;
17864 case 1: printf (_("8-byte\n")); break;
17865 case 2: printf (_("4-byte\n")); break;
17866 case 3: printf ("??? 3\n"); break;
17867 default:
17868 if (val <= 12)
17869 printf (_("8-byte and up to %d-byte extended\n"),
17870 1 << val);
17871 else
17872 printf ("??? (%d)\n", val);
17873 break;
17875 break;
17877 case 25: /* Tag_align_preserved. */
17878 READ_ULEB (val, p, end);
17879 switch (val)
17881 case 0: printf (_("None\n")); break;
17882 case 1: printf (_("8-byte, except leaf SP\n")); break;
17883 case 2: printf (_("8-byte\n")); break;
17884 case 3: printf ("??? 3\n"); break;
17885 default:
17886 if (val <= 12)
17887 printf (_("8-byte and up to %d-byte extended\n"),
17888 1 << val);
17889 else
17890 printf ("??? (%d)\n", val);
17891 break;
17893 break;
17895 case 32: /* Tag_compatibility. */
17897 READ_ULEB (val, p, end);
17898 printf (_("flag = %d, vendor = "), val);
17899 if (p < end - 1)
17901 size_t maxlen = (end - p) - 1;
17903 print_symbol_name ((int) maxlen, (const char *) p);
17904 p += strnlen ((char *) p, maxlen) + 1;
17906 else
17908 printf (_("<corrupt>"));
17909 p = (unsigned char *) end;
17911 putchar ('\n');
17913 break;
17915 case 64: /* Tag_nodefaults. */
17916 /* PR 17531: file: 001-505008-0.01. */
17917 if (p < end)
17918 p++;
17919 printf (_("True\n"));
17920 break;
17922 case 65: /* Tag_also_compatible_with. */
17923 READ_ULEB (val, p, end);
17924 if (val == 6 /* Tag_CPU_arch. */)
17926 READ_ULEB (val, p, end);
17927 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
17928 printf ("??? (%d)\n", val);
17929 else
17930 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
17932 else
17933 printf ("???\n");
17934 while (p < end && *(p++) != '\0' /* NUL terminator. */)
17936 break;
17938 default:
17939 printf (_("<unknown: %d>\n"), tag);
17940 break;
17942 return p;
17944 case 1:
17945 return display_tag_value (-1, p, end);
17946 case 2:
17947 return display_tag_value (0, p, end);
17949 default:
17950 assert (attr->type & 0x80);
17951 READ_ULEB (val, p, end);
17952 type = attr->type & 0x7f;
17953 if (val >= type)
17954 printf ("??? (%d)\n", val);
17955 else
17956 printf ("%s\n", attr->table[val]);
17957 return p;
17961 return display_tag_value (tag, p, end);
17964 static unsigned char *
17965 display_gnu_attribute (unsigned char * p,
17966 unsigned char * (* display_proc_gnu_attribute)
17967 (unsigned char *, unsigned int, const unsigned char * const),
17968 const unsigned char * const end)
17970 unsigned int tag;
17971 unsigned int val;
17973 READ_ULEB (tag, p, end);
17975 /* Tag_compatibility is the only generic GNU attribute defined at
17976 present. */
17977 if (tag == 32)
17979 READ_ULEB (val, p, end);
17981 printf (_("flag = %d, vendor = "), val);
17982 if (p == end)
17984 printf (_("<corrupt>\n"));
17985 warn (_("corrupt vendor attribute\n"));
17987 else
17989 if (p < end - 1)
17991 size_t maxlen = (end - p) - 1;
17993 print_symbol_name ((int) maxlen, (const char *) p);
17994 p += strnlen ((char *) p, maxlen) + 1;
17996 else
17998 printf (_("<corrupt>"));
17999 p = (unsigned char *) end;
18001 putchar ('\n');
18003 return p;
18006 if ((tag & 2) == 0 && display_proc_gnu_attribute)
18007 return display_proc_gnu_attribute (p, tag, end);
18009 return display_tag_value (tag, p, end);
18012 static unsigned char *
18013 display_m68k_gnu_attribute (unsigned char * p,
18014 unsigned int tag,
18015 const unsigned char * const end)
18017 unsigned int val;
18019 if (tag == Tag_GNU_M68K_ABI_FP)
18021 printf (" Tag_GNU_M68K_ABI_FP: ");
18022 if (p == end)
18024 printf (_("<corrupt>\n"));
18025 return p;
18027 READ_ULEB (val, p, end);
18029 if (val > 3)
18030 printf ("(%#x), ", val);
18032 switch (val & 3)
18034 case 0:
18035 printf (_("unspecified hard/soft float\n"));
18036 break;
18037 case 1:
18038 printf (_("hard float\n"));
18039 break;
18040 case 2:
18041 printf (_("soft float\n"));
18042 break;
18044 return p;
18047 return display_tag_value (tag & 1, p, end);
18050 static unsigned char *
18051 display_power_gnu_attribute (unsigned char * p,
18052 unsigned int tag,
18053 const unsigned char * const end)
18055 unsigned int val;
18057 if (tag == Tag_GNU_Power_ABI_FP)
18059 printf (" Tag_GNU_Power_ABI_FP: ");
18060 if (p == end)
18062 printf (_("<corrupt>\n"));
18063 return p;
18065 READ_ULEB (val, p, end);
18067 if (val > 15)
18068 printf ("(%#x), ", val);
18070 switch (val & 3)
18072 case 0:
18073 printf (_("unspecified hard/soft float, "));
18074 break;
18075 case 1:
18076 printf (_("hard float, "));
18077 break;
18078 case 2:
18079 printf (_("soft float, "));
18080 break;
18081 case 3:
18082 printf (_("single-precision hard float, "));
18083 break;
18086 switch (val & 0xC)
18088 case 0:
18089 printf (_("unspecified long double\n"));
18090 break;
18091 case 4:
18092 printf (_("128-bit IBM long double\n"));
18093 break;
18094 case 8:
18095 printf (_("64-bit long double\n"));
18096 break;
18097 case 12:
18098 printf (_("128-bit IEEE long double\n"));
18099 break;
18101 return p;
18104 if (tag == Tag_GNU_Power_ABI_Vector)
18106 printf (" Tag_GNU_Power_ABI_Vector: ");
18107 if (p == end)
18109 printf (_("<corrupt>\n"));
18110 return p;
18112 READ_ULEB (val, p, end);
18114 if (val > 3)
18115 printf ("(%#x), ", val);
18117 switch (val & 3)
18119 case 0:
18120 printf (_("unspecified\n"));
18121 break;
18122 case 1:
18123 printf (_("generic\n"));
18124 break;
18125 case 2:
18126 printf ("AltiVec\n");
18127 break;
18128 case 3:
18129 printf ("SPE\n");
18130 break;
18132 return p;
18135 if (tag == Tag_GNU_Power_ABI_Struct_Return)
18137 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
18138 if (p == end)
18140 printf (_("<corrupt>\n"));
18141 return p;
18143 READ_ULEB (val, p, end);
18145 if (val > 2)
18146 printf ("(%#x), ", val);
18148 switch (val & 3)
18150 case 0:
18151 printf (_("unspecified\n"));
18152 break;
18153 case 1:
18154 printf ("r3/r4\n");
18155 break;
18156 case 2:
18157 printf (_("memory\n"));
18158 break;
18159 case 3:
18160 printf ("???\n");
18161 break;
18163 return p;
18166 return display_tag_value (tag & 1, p, end);
18169 static unsigned char *
18170 display_s390_gnu_attribute (unsigned char * p,
18171 unsigned int tag,
18172 const unsigned char * const end)
18174 unsigned int val;
18176 if (tag == Tag_GNU_S390_ABI_Vector)
18178 printf (" Tag_GNU_S390_ABI_Vector: ");
18179 READ_ULEB (val, p, end);
18181 switch (val)
18183 case 0:
18184 printf (_("any\n"));
18185 break;
18186 case 1:
18187 printf (_("software\n"));
18188 break;
18189 case 2:
18190 printf (_("hardware\n"));
18191 break;
18192 default:
18193 printf ("??? (%d)\n", val);
18194 break;
18196 return p;
18199 return display_tag_value (tag & 1, p, end);
18202 static void
18203 display_sparc_hwcaps (unsigned int mask)
18205 if (mask)
18207 bool first = true;
18209 if (mask & ELF_SPARC_HWCAP_MUL32)
18210 fputs ("mul32", stdout), first = false;
18211 if (mask & ELF_SPARC_HWCAP_DIV32)
18212 printf ("%sdiv32", first ? "" : "|"), first = false;
18213 if (mask & ELF_SPARC_HWCAP_FSMULD)
18214 printf ("%sfsmuld", first ? "" : "|"), first = false;
18215 if (mask & ELF_SPARC_HWCAP_V8PLUS)
18216 printf ("%sv8plus", first ? "" : "|"), first = false;
18217 if (mask & ELF_SPARC_HWCAP_POPC)
18218 printf ("%spopc", first ? "" : "|"), first = false;
18219 if (mask & ELF_SPARC_HWCAP_VIS)
18220 printf ("%svis", first ? "" : "|"), first = false;
18221 if (mask & ELF_SPARC_HWCAP_VIS2)
18222 printf ("%svis2", first ? "" : "|"), first = false;
18223 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
18224 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
18225 if (mask & ELF_SPARC_HWCAP_FMAF)
18226 printf ("%sfmaf", first ? "" : "|"), first = false;
18227 if (mask & ELF_SPARC_HWCAP_VIS3)
18228 printf ("%svis3", first ? "" : "|"), first = false;
18229 if (mask & ELF_SPARC_HWCAP_HPC)
18230 printf ("%shpc", first ? "" : "|"), first = false;
18231 if (mask & ELF_SPARC_HWCAP_RANDOM)
18232 printf ("%srandom", first ? "" : "|"), first = false;
18233 if (mask & ELF_SPARC_HWCAP_TRANS)
18234 printf ("%strans", first ? "" : "|"), first = false;
18235 if (mask & ELF_SPARC_HWCAP_FJFMAU)
18236 printf ("%sfjfmau", first ? "" : "|"), first = false;
18237 if (mask & ELF_SPARC_HWCAP_IMA)
18238 printf ("%sima", first ? "" : "|"), first = false;
18239 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
18240 printf ("%scspare", first ? "" : "|"), first = false;
18242 else
18243 fputc ('0', stdout);
18244 fputc ('\n', stdout);
18247 static void
18248 display_sparc_hwcaps2 (unsigned int mask)
18250 if (mask)
18252 bool first = true;
18254 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
18255 fputs ("fjathplus", stdout), first = false;
18256 if (mask & ELF_SPARC_HWCAP2_VIS3B)
18257 printf ("%svis3b", first ? "" : "|"), first = false;
18258 if (mask & ELF_SPARC_HWCAP2_ADP)
18259 printf ("%sadp", first ? "" : "|"), first = false;
18260 if (mask & ELF_SPARC_HWCAP2_SPARC5)
18261 printf ("%ssparc5", first ? "" : "|"), first = false;
18262 if (mask & ELF_SPARC_HWCAP2_MWAIT)
18263 printf ("%smwait", first ? "" : "|"), first = false;
18264 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
18265 printf ("%sxmpmul", first ? "" : "|"), first = false;
18266 if (mask & ELF_SPARC_HWCAP2_XMONT)
18267 printf ("%sxmont2", first ? "" : "|"), first = false;
18268 if (mask & ELF_SPARC_HWCAP2_NSEC)
18269 printf ("%snsec", first ? "" : "|"), first = false;
18270 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
18271 printf ("%sfjathhpc", first ? "" : "|"), first = false;
18272 if (mask & ELF_SPARC_HWCAP2_FJDES)
18273 printf ("%sfjdes", first ? "" : "|"), first = false;
18274 if (mask & ELF_SPARC_HWCAP2_FJAES)
18275 printf ("%sfjaes", first ? "" : "|"), first = false;
18277 else
18278 fputc ('0', stdout);
18279 fputc ('\n', stdout);
18282 static unsigned char *
18283 display_sparc_gnu_attribute (unsigned char * p,
18284 unsigned int tag,
18285 const unsigned char * const end)
18287 unsigned int val;
18289 if (tag == Tag_GNU_Sparc_HWCAPS)
18291 READ_ULEB (val, p, end);
18292 printf (" Tag_GNU_Sparc_HWCAPS: ");
18293 display_sparc_hwcaps (val);
18294 return p;
18296 if (tag == Tag_GNU_Sparc_HWCAPS2)
18298 READ_ULEB (val, p, end);
18299 printf (" Tag_GNU_Sparc_HWCAPS2: ");
18300 display_sparc_hwcaps2 (val);
18301 return p;
18304 return display_tag_value (tag, p, end);
18307 static void
18308 print_mips_fp_abi_value (unsigned int val)
18310 switch (val)
18312 case Val_GNU_MIPS_ABI_FP_ANY:
18313 printf (_("Hard or soft float\n"));
18314 break;
18315 case Val_GNU_MIPS_ABI_FP_DOUBLE:
18316 printf (_("Hard float (double precision)\n"));
18317 break;
18318 case Val_GNU_MIPS_ABI_FP_SINGLE:
18319 printf (_("Hard float (single precision)\n"));
18320 break;
18321 case Val_GNU_MIPS_ABI_FP_SOFT:
18322 printf (_("Soft float\n"));
18323 break;
18324 case Val_GNU_MIPS_ABI_FP_OLD_64:
18325 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
18326 break;
18327 case Val_GNU_MIPS_ABI_FP_XX:
18328 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
18329 break;
18330 case Val_GNU_MIPS_ABI_FP_64:
18331 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
18332 break;
18333 case Val_GNU_MIPS_ABI_FP_64A:
18334 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
18335 break;
18336 case Val_GNU_MIPS_ABI_FP_NAN2008:
18337 printf (_("NaN 2008 compatibility\n"));
18338 break;
18339 default:
18340 printf ("??? (%d)\n", val);
18341 break;
18345 static unsigned char *
18346 display_mips_gnu_attribute (unsigned char * p,
18347 unsigned int tag,
18348 const unsigned char * const end)
18350 if (tag == Tag_GNU_MIPS_ABI_FP)
18352 unsigned int val;
18354 printf (" Tag_GNU_MIPS_ABI_FP: ");
18355 READ_ULEB (val, p, end);
18356 print_mips_fp_abi_value (val);
18357 return p;
18360 if (tag == Tag_GNU_MIPS_ABI_MSA)
18362 unsigned int val;
18364 printf (" Tag_GNU_MIPS_ABI_MSA: ");
18365 READ_ULEB (val, p, end);
18367 switch (val)
18369 case Val_GNU_MIPS_ABI_MSA_ANY:
18370 printf (_("Any MSA or not\n"));
18371 break;
18372 case Val_GNU_MIPS_ABI_MSA_128:
18373 printf (_("128-bit MSA\n"));
18374 break;
18375 default:
18376 printf ("??? (%d)\n", val);
18377 break;
18379 return p;
18382 return display_tag_value (tag & 1, p, end);
18385 static unsigned char *
18386 display_tic6x_attribute (unsigned char * p,
18387 const unsigned char * const end)
18389 unsigned int tag;
18390 unsigned int val;
18392 READ_ULEB (tag, p, end);
18394 switch (tag)
18396 case Tag_ISA:
18397 printf (" Tag_ISA: ");
18398 READ_ULEB (val, p, end);
18400 switch (val)
18402 case C6XABI_Tag_ISA_none:
18403 printf (_("None\n"));
18404 break;
18405 case C6XABI_Tag_ISA_C62X:
18406 printf ("C62x\n");
18407 break;
18408 case C6XABI_Tag_ISA_C67X:
18409 printf ("C67x\n");
18410 break;
18411 case C6XABI_Tag_ISA_C67XP:
18412 printf ("C67x+\n");
18413 break;
18414 case C6XABI_Tag_ISA_C64X:
18415 printf ("C64x\n");
18416 break;
18417 case C6XABI_Tag_ISA_C64XP:
18418 printf ("C64x+\n");
18419 break;
18420 case C6XABI_Tag_ISA_C674X:
18421 printf ("C674x\n");
18422 break;
18423 default:
18424 printf ("??? (%d)\n", val);
18425 break;
18427 return p;
18429 case Tag_ABI_wchar_t:
18430 printf (" Tag_ABI_wchar_t: ");
18431 READ_ULEB (val, p, end);
18432 switch (val)
18434 case 0:
18435 printf (_("Not used\n"));
18436 break;
18437 case 1:
18438 printf (_("2 bytes\n"));
18439 break;
18440 case 2:
18441 printf (_("4 bytes\n"));
18442 break;
18443 default:
18444 printf ("??? (%d)\n", val);
18445 break;
18447 return p;
18449 case Tag_ABI_stack_align_needed:
18450 printf (" Tag_ABI_stack_align_needed: ");
18451 READ_ULEB (val, p, end);
18452 switch (val)
18454 case 0:
18455 printf (_("8-byte\n"));
18456 break;
18457 case 1:
18458 printf (_("16-byte\n"));
18459 break;
18460 default:
18461 printf ("??? (%d)\n", val);
18462 break;
18464 return p;
18466 case Tag_ABI_stack_align_preserved:
18467 READ_ULEB (val, p, end);
18468 printf (" Tag_ABI_stack_align_preserved: ");
18469 switch (val)
18471 case 0:
18472 printf (_("8-byte\n"));
18473 break;
18474 case 1:
18475 printf (_("16-byte\n"));
18476 break;
18477 default:
18478 printf ("??? (%d)\n", val);
18479 break;
18481 return p;
18483 case Tag_ABI_DSBT:
18484 READ_ULEB (val, p, end);
18485 printf (" Tag_ABI_DSBT: ");
18486 switch (val)
18488 case 0:
18489 printf (_("DSBT addressing not used\n"));
18490 break;
18491 case 1:
18492 printf (_("DSBT addressing used\n"));
18493 break;
18494 default:
18495 printf ("??? (%d)\n", val);
18496 break;
18498 return p;
18500 case Tag_ABI_PID:
18501 READ_ULEB (val, p, end);
18502 printf (" Tag_ABI_PID: ");
18503 switch (val)
18505 case 0:
18506 printf (_("Data addressing position-dependent\n"));
18507 break;
18508 case 1:
18509 printf (_("Data addressing position-independent, GOT near DP\n"));
18510 break;
18511 case 2:
18512 printf (_("Data addressing position-independent, GOT far from DP\n"));
18513 break;
18514 default:
18515 printf ("??? (%d)\n", val);
18516 break;
18518 return p;
18520 case Tag_ABI_PIC:
18521 READ_ULEB (val, p, end);
18522 printf (" Tag_ABI_PIC: ");
18523 switch (val)
18525 case 0:
18526 printf (_("Code addressing position-dependent\n"));
18527 break;
18528 case 1:
18529 printf (_("Code addressing position-independent\n"));
18530 break;
18531 default:
18532 printf ("??? (%d)\n", val);
18533 break;
18535 return p;
18537 case Tag_ABI_array_object_alignment:
18538 READ_ULEB (val, p, end);
18539 printf (" Tag_ABI_array_object_alignment: ");
18540 switch (val)
18542 case 0:
18543 printf (_("8-byte\n"));
18544 break;
18545 case 1:
18546 printf (_("4-byte\n"));
18547 break;
18548 case 2:
18549 printf (_("16-byte\n"));
18550 break;
18551 default:
18552 printf ("??? (%d)\n", val);
18553 break;
18555 return p;
18557 case Tag_ABI_array_object_align_expected:
18558 READ_ULEB (val, p, end);
18559 printf (" Tag_ABI_array_object_align_expected: ");
18560 switch (val)
18562 case 0:
18563 printf (_("8-byte\n"));
18564 break;
18565 case 1:
18566 printf (_("4-byte\n"));
18567 break;
18568 case 2:
18569 printf (_("16-byte\n"));
18570 break;
18571 default:
18572 printf ("??? (%d)\n", val);
18573 break;
18575 return p;
18577 case Tag_ABI_compatibility:
18579 READ_ULEB (val, p, end);
18580 printf (" Tag_ABI_compatibility: ");
18581 printf (_("flag = %d, vendor = "), val);
18582 if (p < end - 1)
18584 size_t maxlen = (end - p) - 1;
18586 print_symbol_name ((int) maxlen, (const char *) p);
18587 p += strnlen ((char *) p, maxlen) + 1;
18589 else
18591 printf (_("<corrupt>"));
18592 p = (unsigned char *) end;
18594 putchar ('\n');
18595 return p;
18598 case Tag_ABI_conformance:
18600 printf (" Tag_ABI_conformance: \"");
18601 if (p < end - 1)
18603 size_t maxlen = (end - p) - 1;
18605 print_symbol_name ((int) maxlen, (const char *) p);
18606 p += strnlen ((char *) p, maxlen) + 1;
18608 else
18610 printf (_("<corrupt>"));
18611 p = (unsigned char *) end;
18613 printf ("\"\n");
18614 return p;
18618 return display_tag_value (tag, p, end);
18621 static void
18622 display_raw_attribute (unsigned char * p, unsigned char const * const end)
18624 uint64_t addr = 0;
18625 size_t bytes = end - p;
18627 assert (end >= p);
18628 while (bytes)
18630 int j;
18631 int k;
18632 int lbytes = (bytes > 16 ? 16 : bytes);
18634 printf (" 0x%8.8" PRIx64 " ", addr);
18636 for (j = 0; j < 16; j++)
18638 if (j < lbytes)
18639 printf ("%2.2x", p[j]);
18640 else
18641 printf (" ");
18643 if ((j & 3) == 3)
18644 printf (" ");
18647 for (j = 0; j < lbytes; j++)
18649 k = p[j];
18650 if (k >= ' ' && k < 0x7f)
18651 printf ("%c", k);
18652 else
18653 printf (".");
18656 putchar ('\n');
18658 p += lbytes;
18659 bytes -= lbytes;
18660 addr += lbytes;
18663 putchar ('\n');
18666 static unsigned char *
18667 display_msp430_attribute (unsigned char * p,
18668 const unsigned char * const end)
18670 uint64_t val;
18671 uint64_t tag;
18673 READ_ULEB (tag, p, end);
18675 switch (tag)
18677 case OFBA_MSPABI_Tag_ISA:
18678 printf (" Tag_ISA: ");
18679 READ_ULEB (val, p, end);
18680 switch (val)
18682 case 0: printf (_("None\n")); break;
18683 case 1: printf (_("MSP430\n")); break;
18684 case 2: printf (_("MSP430X\n")); break;
18685 default: printf ("??? (%" PRId64 ")\n", val); break;
18687 break;
18689 case OFBA_MSPABI_Tag_Code_Model:
18690 printf (" Tag_Code_Model: ");
18691 READ_ULEB (val, p, end);
18692 switch (val)
18694 case 0: printf (_("None\n")); break;
18695 case 1: printf (_("Small\n")); break;
18696 case 2: printf (_("Large\n")); break;
18697 default: printf ("??? (%" PRId64 ")\n", val); break;
18699 break;
18701 case OFBA_MSPABI_Tag_Data_Model:
18702 printf (" Tag_Data_Model: ");
18703 READ_ULEB (val, p, end);
18704 switch (val)
18706 case 0: printf (_("None\n")); break;
18707 case 1: printf (_("Small\n")); break;
18708 case 2: printf (_("Large\n")); break;
18709 case 3: printf (_("Restricted Large\n")); break;
18710 default: printf ("??? (%" PRId64 ")\n", val); break;
18712 break;
18714 default:
18715 printf (_(" <unknown tag %" PRId64 ">: "), tag);
18717 if (tag & 1)
18719 putchar ('"');
18720 if (p < end - 1)
18722 size_t maxlen = (end - p) - 1;
18724 print_symbol_name ((int) maxlen, (const char *) p);
18725 p += strnlen ((char *) p, maxlen) + 1;
18727 else
18729 printf (_("<corrupt>"));
18730 p = (unsigned char *) end;
18732 printf ("\"\n");
18734 else
18736 READ_ULEB (val, p, end);
18737 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
18739 break;
18742 assert (p <= end);
18743 return p;
18746 static unsigned char *
18747 display_msp430_gnu_attribute (unsigned char * p,
18748 unsigned int tag,
18749 const unsigned char * const end)
18751 if (tag == Tag_GNU_MSP430_Data_Region)
18753 uint64_t val;
18755 printf (" Tag_GNU_MSP430_Data_Region: ");
18756 READ_ULEB (val, p, end);
18758 switch (val)
18760 case Val_GNU_MSP430_Data_Region_Any:
18761 printf (_("Any Region\n"));
18762 break;
18763 case Val_GNU_MSP430_Data_Region_Lower:
18764 printf (_("Lower Region Only\n"));
18765 break;
18766 default:
18767 printf ("??? (%" PRIu64 ")\n", val);
18769 return p;
18771 return display_tag_value (tag & 1, p, end);
18774 struct riscv_attr_tag_t {
18775 const char *name;
18776 unsigned int tag;
18779 static struct riscv_attr_tag_t riscv_attr_tag[] =
18781 #define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
18782 T(arch),
18783 T(priv_spec),
18784 T(priv_spec_minor),
18785 T(priv_spec_revision),
18786 T(unaligned_access),
18787 T(stack_align),
18788 #undef T
18791 static unsigned char *
18792 display_riscv_attribute (unsigned char *p,
18793 const unsigned char * const end)
18795 uint64_t val;
18796 uint64_t tag;
18797 struct riscv_attr_tag_t *attr = NULL;
18798 unsigned i;
18800 READ_ULEB (tag, p, end);
18802 /* Find the name of attribute. */
18803 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
18805 if (riscv_attr_tag[i].tag == tag)
18807 attr = &riscv_attr_tag[i];
18808 break;
18812 if (attr)
18813 printf (" %s: ", attr->name);
18814 else
18815 return display_tag_value (tag, p, end);
18817 switch (tag)
18819 case Tag_RISCV_priv_spec:
18820 case Tag_RISCV_priv_spec_minor:
18821 case Tag_RISCV_priv_spec_revision:
18822 READ_ULEB (val, p, end);
18823 printf ("%" PRIu64 "\n", val);
18824 break;
18825 case Tag_RISCV_unaligned_access:
18826 READ_ULEB (val, p, end);
18827 switch (val)
18829 case 0:
18830 printf (_("No unaligned access\n"));
18831 break;
18832 case 1:
18833 printf (_("Unaligned access\n"));
18834 break;
18836 break;
18837 case Tag_RISCV_stack_align:
18838 READ_ULEB (val, p, end);
18839 printf (_("%" PRIu64 "-bytes\n"), val);
18840 break;
18841 case Tag_RISCV_arch:
18842 p = display_tag_value (-1, p, end);
18843 break;
18844 default:
18845 return display_tag_value (tag, p, end);
18848 return p;
18851 static unsigned char *
18852 display_csky_attribute (unsigned char * p,
18853 const unsigned char * const end)
18855 uint64_t tag;
18856 uint64_t val;
18857 READ_ULEB (tag, p, end);
18859 if (tag >= Tag_CSKY_MAX)
18861 return display_tag_value (-1, p, end);
18864 switch (tag)
18866 case Tag_CSKY_ARCH_NAME:
18867 printf (" Tag_CSKY_ARCH_NAME:\t\t");
18868 return display_tag_value (-1, p, end);
18869 case Tag_CSKY_CPU_NAME:
18870 printf (" Tag_CSKY_CPU_NAME:\t\t");
18871 return display_tag_value (-1, p, end);
18873 case Tag_CSKY_ISA_FLAGS:
18874 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
18875 return display_tag_value (0, p, end);
18876 case Tag_CSKY_ISA_EXT_FLAGS:
18877 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
18878 return display_tag_value (0, p, end);
18880 case Tag_CSKY_DSP_VERSION:
18881 printf (" Tag_CSKY_DSP_VERSION:\t\t");
18882 READ_ULEB (val, p, end);
18883 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
18884 printf ("DSP Extension\n");
18885 else if (val == VAL_CSKY_DSP_VERSION_2)
18886 printf ("DSP 2.0\n");
18887 break;
18889 case Tag_CSKY_VDSP_VERSION:
18890 printf (" Tag_CSKY_VDSP_VERSION:\t");
18891 READ_ULEB (val, p, end);
18892 printf ("VDSP Version %" PRId64 "\n", val);
18893 break;
18895 case Tag_CSKY_FPU_VERSION:
18896 printf (" Tag_CSKY_FPU_VERSION:\t\t");
18897 READ_ULEB (val, p, end);
18898 if (val == VAL_CSKY_FPU_VERSION_1)
18899 printf ("ABIV1 FPU Version 1\n");
18900 else if (val == VAL_CSKY_FPU_VERSION_2)
18901 printf ("FPU Version 2\n");
18902 break;
18904 case Tag_CSKY_FPU_ABI:
18905 printf (" Tag_CSKY_FPU_ABI:\t\t");
18906 READ_ULEB (val, p, end);
18907 if (val == VAL_CSKY_FPU_ABI_HARD)
18908 printf ("Hard\n");
18909 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
18910 printf ("SoftFP\n");
18911 else if (val == VAL_CSKY_FPU_ABI_SOFT)
18912 printf ("Soft\n");
18913 break;
18914 case Tag_CSKY_FPU_ROUNDING:
18915 READ_ULEB (val, p, end);
18916 if (val == 1)
18918 printf (" Tag_CSKY_FPU_ROUNDING:\t");
18919 printf ("Needed\n");
18921 break;
18922 case Tag_CSKY_FPU_DENORMAL:
18923 READ_ULEB (val, p, end);
18924 if (val == 1)
18926 printf (" Tag_CSKY_FPU_DENORMAL:\t");
18927 printf ("Needed\n");
18929 break;
18930 case Tag_CSKY_FPU_Exception:
18931 READ_ULEB (val, p, end);
18932 if (val == 1)
18934 printf (" Tag_CSKY_FPU_Exception:\t");
18935 printf ("Needed\n");
18937 break;
18938 case Tag_CSKY_FPU_NUMBER_MODULE:
18939 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
18940 return display_tag_value (-1, p, end);
18941 case Tag_CSKY_FPU_HARDFP:
18942 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
18943 READ_ULEB (val, p, end);
18944 if (val & VAL_CSKY_FPU_HARDFP_HALF)
18945 printf (" Half");
18946 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
18947 printf (" Single");
18948 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
18949 printf (" Double");
18950 printf ("\n");
18951 break;
18952 default:
18953 return display_tag_value (tag, p, end);
18955 return p;
18958 static bool
18959 process_attributes (Filedata * filedata,
18960 const char * public_name,
18961 unsigned int proc_type,
18962 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
18963 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
18965 Elf_Internal_Shdr * sect;
18966 unsigned i;
18967 bool res = true;
18969 /* Find the section header so that we get the size. */
18970 for (i = 0, sect = filedata->section_headers;
18971 i < filedata->file_header.e_shnum;
18972 i++, sect++)
18974 unsigned char * contents;
18975 unsigned char * p;
18977 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
18978 continue;
18980 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
18981 sect->sh_size, _("attributes"));
18982 if (contents == NULL)
18984 res = false;
18985 continue;
18988 p = contents;
18989 /* The first character is the version of the attributes.
18990 Currently only version 1, (aka 'A') is recognised here. */
18991 if (*p != 'A')
18993 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
18994 res = false;
18996 else
18998 uint64_t section_len;
19000 section_len = sect->sh_size - 1;
19001 p++;
19003 while (section_len > 0)
19005 uint64_t attr_len;
19006 unsigned int namelen;
19007 bool public_section;
19008 bool gnu_section;
19010 if (section_len <= 4)
19012 error (_("Tag section ends prematurely\n"));
19013 res = false;
19014 break;
19016 attr_len = byte_get (p, 4);
19017 p += 4;
19019 if (attr_len > section_len)
19021 error (_("Bad attribute length (%u > %u)\n"),
19022 (unsigned) attr_len, (unsigned) section_len);
19023 attr_len = section_len;
19024 res = false;
19026 /* PR 17531: file: 001-101425-0.004 */
19027 else if (attr_len < 5)
19029 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
19030 res = false;
19031 break;
19034 section_len -= attr_len;
19035 attr_len -= 4;
19037 namelen = strnlen ((char *) p, attr_len) + 1;
19038 if (namelen == 0 || namelen >= attr_len)
19040 error (_("Corrupt attribute section name\n"));
19041 res = false;
19042 break;
19045 printf (_("Attribute Section: "));
19046 print_symbol_name (INT_MAX, (const char *) p);
19047 putchar ('\n');
19049 if (public_name && streq ((char *) p, public_name))
19050 public_section = true;
19051 else
19052 public_section = false;
19054 if (streq ((char *) p, "gnu"))
19055 gnu_section = true;
19056 else
19057 gnu_section = false;
19059 p += namelen;
19060 attr_len -= namelen;
19062 while (attr_len > 0 && p < contents + sect->sh_size)
19064 int tag;
19065 unsigned int val;
19066 uint64_t size;
19067 unsigned char * end;
19069 /* PR binutils/17531: Safe handling of corrupt files. */
19070 if (attr_len < 6)
19072 error (_("Unused bytes at end of section\n"));
19073 res = false;
19074 section_len = 0;
19075 break;
19078 tag = *(p++);
19079 size = byte_get (p, 4);
19080 if (size > attr_len)
19082 error (_("Bad subsection length (%u > %u)\n"),
19083 (unsigned) size, (unsigned) attr_len);
19084 res = false;
19085 size = attr_len;
19087 /* PR binutils/17531: Safe handling of corrupt files. */
19088 if (size < 6)
19090 error (_("Bad subsection length (%u < 6)\n"),
19091 (unsigned) size);
19092 res = false;
19093 section_len = 0;
19094 break;
19097 attr_len -= size;
19098 end = p + size - 1;
19099 assert (end <= contents + sect->sh_size);
19100 p += 4;
19102 switch (tag)
19104 case 1:
19105 printf (_("File Attributes\n"));
19106 break;
19107 case 2:
19108 printf (_("Section Attributes:"));
19109 goto do_numlist;
19110 case 3:
19111 printf (_("Symbol Attributes:"));
19112 /* Fall through. */
19113 do_numlist:
19114 for (;;)
19116 READ_ULEB (val, p, end);
19117 if (val == 0)
19118 break;
19119 printf (" %d", val);
19121 printf ("\n");
19122 break;
19123 default:
19124 printf (_("Unknown tag: %d\n"), tag);
19125 public_section = false;
19126 break;
19129 if (public_section && display_pub_attribute != NULL)
19131 while (p < end)
19132 p = display_pub_attribute (p, end);
19133 assert (p == end);
19135 else if (gnu_section && display_proc_gnu_attribute != NULL)
19137 while (p < end)
19138 p = display_gnu_attribute (p,
19139 display_proc_gnu_attribute,
19140 end);
19141 assert (p == end);
19143 else if (p < end)
19145 printf (_(" Unknown attribute:\n"));
19146 display_raw_attribute (p, end);
19147 p = end;
19149 else
19150 attr_len = 0;
19155 free (contents);
19158 return res;
19161 /* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
19162 Print the Address, Access and Initial fields of an entry at VMA ADDR
19163 and return the VMA of the next entry, or -1 if there was a problem.
19164 Does not read from DATA_END or beyond. */
19166 static uint64_t
19167 print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
19168 unsigned char * data_end)
19170 printf (" ");
19171 print_vma (addr, LONG_HEX);
19172 printf (" ");
19173 if (addr < pltgot + 0xfff0)
19174 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
19175 else
19176 printf ("%10s", "");
19177 printf (" ");
19178 if (data == NULL)
19179 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
19180 else
19182 uint64_t entry;
19183 unsigned char * from = data + addr - pltgot;
19185 if (from + (is_32bit_elf ? 4 : 8) > data_end)
19187 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
19188 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
19189 return (uint64_t) -1;
19191 else
19193 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
19194 print_vma (entry, LONG_HEX);
19197 return addr + (is_32bit_elf ? 4 : 8);
19200 /* DATA points to the contents of a MIPS PLT GOT that starts at VMA
19201 PLTGOT. Print the Address and Initial fields of an entry at VMA
19202 ADDR and return the VMA of the next entry. */
19204 static uint64_t
19205 print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
19207 printf (" ");
19208 print_vma (addr, LONG_HEX);
19209 printf (" ");
19210 if (data == NULL)
19211 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
19212 else
19214 uint64_t entry;
19216 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
19217 print_vma (entry, LONG_HEX);
19219 return addr + (is_32bit_elf ? 4 : 8);
19222 static void
19223 print_mips_ases (unsigned int mask)
19225 if (mask & AFL_ASE_DSP)
19226 fputs ("\n\tDSP ASE", stdout);
19227 if (mask & AFL_ASE_DSPR2)
19228 fputs ("\n\tDSP R2 ASE", stdout);
19229 if (mask & AFL_ASE_DSPR3)
19230 fputs ("\n\tDSP R3 ASE", stdout);
19231 if (mask & AFL_ASE_EVA)
19232 fputs ("\n\tEnhanced VA Scheme", stdout);
19233 if (mask & AFL_ASE_MCU)
19234 fputs ("\n\tMCU (MicroController) ASE", stdout);
19235 if (mask & AFL_ASE_MDMX)
19236 fputs ("\n\tMDMX ASE", stdout);
19237 if (mask & AFL_ASE_MIPS3D)
19238 fputs ("\n\tMIPS-3D ASE", stdout);
19239 if (mask & AFL_ASE_MT)
19240 fputs ("\n\tMT ASE", stdout);
19241 if (mask & AFL_ASE_SMARTMIPS)
19242 fputs ("\n\tSmartMIPS ASE", stdout);
19243 if (mask & AFL_ASE_VIRT)
19244 fputs ("\n\tVZ ASE", stdout);
19245 if (mask & AFL_ASE_MSA)
19246 fputs ("\n\tMSA ASE", stdout);
19247 if (mask & AFL_ASE_MIPS16)
19248 fputs ("\n\tMIPS16 ASE", stdout);
19249 if (mask & AFL_ASE_MICROMIPS)
19250 fputs ("\n\tMICROMIPS ASE", stdout);
19251 if (mask & AFL_ASE_XPA)
19252 fputs ("\n\tXPA ASE", stdout);
19253 if (mask & AFL_ASE_MIPS16E2)
19254 fputs ("\n\tMIPS16e2 ASE", stdout);
19255 if (mask & AFL_ASE_CRC)
19256 fputs ("\n\tCRC ASE", stdout);
19257 if (mask & AFL_ASE_GINV)
19258 fputs ("\n\tGINV ASE", stdout);
19259 if (mask & AFL_ASE_LOONGSON_MMI)
19260 fputs ("\n\tLoongson MMI ASE", stdout);
19261 if (mask & AFL_ASE_LOONGSON_CAM)
19262 fputs ("\n\tLoongson CAM ASE", stdout);
19263 if (mask & AFL_ASE_LOONGSON_EXT)
19264 fputs ("\n\tLoongson EXT ASE", stdout);
19265 if (mask & AFL_ASE_LOONGSON_EXT2)
19266 fputs ("\n\tLoongson EXT2 ASE", stdout);
19267 if (mask == 0)
19268 fprintf (stdout, "\n\t%s", _("None"));
19269 else if ((mask & ~AFL_ASE_MASK) != 0)
19270 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
19273 static void
19274 print_mips_isa_ext (unsigned int isa_ext)
19276 switch (isa_ext)
19278 case 0:
19279 fputs (_("None"), stdout);
19280 break;
19281 case AFL_EXT_XLR:
19282 fputs ("RMI XLR", stdout);
19283 break;
19284 case AFL_EXT_OCTEON3:
19285 fputs ("Cavium Networks Octeon3", stdout);
19286 break;
19287 case AFL_EXT_OCTEON2:
19288 fputs ("Cavium Networks Octeon2", stdout);
19289 break;
19290 case AFL_EXT_OCTEONP:
19291 fputs ("Cavium Networks OcteonP", stdout);
19292 break;
19293 case AFL_EXT_OCTEON:
19294 fputs ("Cavium Networks Octeon", stdout);
19295 break;
19296 case AFL_EXT_5900:
19297 fputs ("Toshiba R5900", stdout);
19298 break;
19299 case AFL_EXT_4650:
19300 fputs ("MIPS R4650", stdout);
19301 break;
19302 case AFL_EXT_4010:
19303 fputs ("LSI R4010", stdout);
19304 break;
19305 case AFL_EXT_4100:
19306 fputs ("NEC VR4100", stdout);
19307 break;
19308 case AFL_EXT_3900:
19309 fputs ("Toshiba R3900", stdout);
19310 break;
19311 case AFL_EXT_10000:
19312 fputs ("MIPS R10000", stdout);
19313 break;
19314 case AFL_EXT_SB1:
19315 fputs ("Broadcom SB-1", stdout);
19316 break;
19317 case AFL_EXT_4111:
19318 fputs ("NEC VR4111/VR4181", stdout);
19319 break;
19320 case AFL_EXT_4120:
19321 fputs ("NEC VR4120", stdout);
19322 break;
19323 case AFL_EXT_5400:
19324 fputs ("NEC VR5400", stdout);
19325 break;
19326 case AFL_EXT_5500:
19327 fputs ("NEC VR5500", stdout);
19328 break;
19329 case AFL_EXT_LOONGSON_2E:
19330 fputs ("ST Microelectronics Loongson 2E", stdout);
19331 break;
19332 case AFL_EXT_LOONGSON_2F:
19333 fputs ("ST Microelectronics Loongson 2F", stdout);
19334 break;
19335 case AFL_EXT_INTERAPTIV_MR2:
19336 fputs ("Imagination interAptiv MR2", stdout);
19337 break;
19338 default:
19339 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
19343 static signed int
19344 get_mips_reg_size (int reg_size)
19346 return (reg_size == AFL_REG_NONE) ? 0
19347 : (reg_size == AFL_REG_32) ? 32
19348 : (reg_size == AFL_REG_64) ? 64
19349 : (reg_size == AFL_REG_128) ? 128
19350 : -1;
19353 static bool
19354 process_mips_specific (Filedata * filedata)
19356 Elf_Internal_Dyn * entry;
19357 Elf_Internal_Shdr *sect = NULL;
19358 size_t liblist_offset = 0;
19359 size_t liblistno = 0;
19360 size_t conflictsno = 0;
19361 size_t options_offset = 0;
19362 size_t conflicts_offset = 0;
19363 size_t pltrelsz = 0;
19364 size_t pltrel = 0;
19365 uint64_t pltgot = 0;
19366 uint64_t mips_pltgot = 0;
19367 uint64_t jmprel = 0;
19368 uint64_t local_gotno = 0;
19369 uint64_t gotsym = 0;
19370 uint64_t symtabno = 0;
19371 bool res = true;
19373 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
19374 display_mips_gnu_attribute))
19375 res = false;
19377 sect = find_section (filedata, ".MIPS.abiflags");
19379 if (sect != NULL)
19381 Elf_External_ABIFlags_v0 *abiflags_ext;
19382 Elf_Internal_ABIFlags_v0 abiflags_in;
19384 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
19386 error (_("Corrupt MIPS ABI Flags section.\n"));
19387 res = false;
19389 else
19391 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
19392 sect->sh_size, _("MIPS ABI Flags section"));
19393 if (abiflags_ext)
19395 abiflags_in.version = BYTE_GET (abiflags_ext->version);
19396 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
19397 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
19398 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
19399 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
19400 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
19401 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
19402 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
19403 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
19404 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
19405 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
19407 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
19408 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
19409 if (abiflags_in.isa_rev > 1)
19410 printf ("r%d", abiflags_in.isa_rev);
19411 printf ("\nGPR size: %d",
19412 get_mips_reg_size (abiflags_in.gpr_size));
19413 printf ("\nCPR1 size: %d",
19414 get_mips_reg_size (abiflags_in.cpr1_size));
19415 printf ("\nCPR2 size: %d",
19416 get_mips_reg_size (abiflags_in.cpr2_size));
19417 fputs ("\nFP ABI: ", stdout);
19418 print_mips_fp_abi_value (abiflags_in.fp_abi);
19419 fputs ("ISA Extension: ", stdout);
19420 print_mips_isa_ext (abiflags_in.isa_ext);
19421 fputs ("\nASEs:", stdout);
19422 print_mips_ases (abiflags_in.ases);
19423 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
19424 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
19425 fputc ('\n', stdout);
19426 free (abiflags_ext);
19431 /* We have a lot of special sections. Thanks SGI! */
19432 if (filedata->dynamic_section == NULL)
19434 /* No dynamic information available. See if there is static GOT. */
19435 sect = find_section (filedata, ".got");
19436 if (sect != NULL)
19438 unsigned char *data_end;
19439 unsigned char *data;
19440 uint64_t ent, end;
19441 int addr_size;
19443 pltgot = sect->sh_addr;
19445 ent = pltgot;
19446 addr_size = (is_32bit_elf ? 4 : 8);
19447 end = pltgot + sect->sh_size;
19449 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
19450 end - pltgot, 1,
19451 _("Global Offset Table data"));
19452 /* PR 12855: Null data is handled gracefully throughout. */
19453 data_end = data + (end - pltgot);
19455 printf (_("\nStatic GOT:\n"));
19456 printf (_(" Canonical gp value: "));
19457 print_vma (ent + 0x7ff0, LONG_HEX);
19458 printf ("\n\n");
19460 /* In a dynamic binary GOT[0] is reserved for the dynamic
19461 loader to store the lazy resolver pointer, however in
19462 a static binary it may well have been omitted and GOT
19463 reduced to a table of addresses.
19464 PR 21344: Check for the entry being fully available
19465 before fetching it. */
19466 if (data
19467 && data + ent - pltgot + addr_size <= data_end
19468 && byte_get (data + ent - pltgot, addr_size) == 0)
19470 printf (_(" Reserved entries:\n"));
19471 printf (_(" %*s %10s %*s\n"),
19472 addr_size * 2, _("Address"), _("Access"),
19473 addr_size * 2, _("Value"));
19474 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19475 printf ("\n");
19476 if (ent == (uint64_t) -1)
19477 goto sgot_print_fail;
19479 /* Check for the MSB of GOT[1] being set, identifying a
19480 GNU object. This entry will be used by some runtime
19481 loaders, to store the module pointer. Otherwise this
19482 is an ordinary local entry.
19483 PR 21344: Check for the entry being fully available
19484 before fetching it. */
19485 if (data
19486 && data + ent - pltgot + addr_size <= data_end
19487 && (byte_get (data + ent - pltgot, addr_size)
19488 >> (addr_size * 8 - 1)) != 0)
19490 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19491 printf ("\n");
19492 if (ent == (uint64_t) -1)
19493 goto sgot_print_fail;
19495 printf ("\n");
19498 if (data != NULL && ent < end)
19500 printf (_(" Local entries:\n"));
19501 printf (" %*s %10s %*s\n",
19502 addr_size * 2, _("Address"), _("Access"),
19503 addr_size * 2, _("Value"));
19504 while (ent < end)
19506 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19507 printf ("\n");
19508 if (ent == (uint64_t) -1)
19509 goto sgot_print_fail;
19511 printf ("\n");
19514 sgot_print_fail:
19515 free (data);
19517 return res;
19520 for (entry = filedata->dynamic_section;
19521 /* PR 17531 file: 012-50589-0.004. */
19522 (entry < filedata->dynamic_section + filedata->dynamic_nent
19523 && entry->d_tag != DT_NULL);
19524 ++entry)
19525 switch (entry->d_tag)
19527 case DT_MIPS_LIBLIST:
19528 liblist_offset
19529 = offset_from_vma (filedata, entry->d_un.d_val,
19530 liblistno * sizeof (Elf32_External_Lib));
19531 break;
19532 case DT_MIPS_LIBLISTNO:
19533 liblistno = entry->d_un.d_val;
19534 break;
19535 case DT_MIPS_OPTIONS:
19536 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
19537 break;
19538 case DT_MIPS_CONFLICT:
19539 conflicts_offset
19540 = offset_from_vma (filedata, entry->d_un.d_val,
19541 conflictsno * sizeof (Elf32_External_Conflict));
19542 break;
19543 case DT_MIPS_CONFLICTNO:
19544 conflictsno = entry->d_un.d_val;
19545 break;
19546 case DT_PLTGOT:
19547 pltgot = entry->d_un.d_ptr;
19548 break;
19549 case DT_MIPS_LOCAL_GOTNO:
19550 local_gotno = entry->d_un.d_val;
19551 break;
19552 case DT_MIPS_GOTSYM:
19553 gotsym = entry->d_un.d_val;
19554 break;
19555 case DT_MIPS_SYMTABNO:
19556 symtabno = entry->d_un.d_val;
19557 break;
19558 case DT_MIPS_PLTGOT:
19559 mips_pltgot = entry->d_un.d_ptr;
19560 break;
19561 case DT_PLTREL:
19562 pltrel = entry->d_un.d_val;
19563 break;
19564 case DT_PLTRELSZ:
19565 pltrelsz = entry->d_un.d_val;
19566 break;
19567 case DT_JMPREL:
19568 jmprel = entry->d_un.d_ptr;
19569 break;
19570 default:
19571 break;
19574 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
19576 Elf32_External_Lib * elib;
19577 size_t cnt;
19579 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
19580 sizeof (Elf32_External_Lib),
19581 liblistno,
19582 _("liblist section data"));
19583 if (elib)
19585 printf (ngettext ("\nSection '.liblist' contains %zu entry:\n",
19586 "\nSection '.liblist' contains %zu entries:\n",
19587 liblistno),
19588 liblistno);
19589 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
19590 stdout);
19592 for (cnt = 0; cnt < liblistno; ++cnt)
19594 Elf32_Lib liblist;
19595 time_t atime;
19596 char timebuf[128];
19597 struct tm * tmp;
19599 liblist.l_name = BYTE_GET (elib[cnt].l_name);
19600 atime = BYTE_GET (elib[cnt].l_time_stamp);
19601 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19602 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19603 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19605 tmp = gmtime (&atime);
19606 snprintf (timebuf, sizeof (timebuf),
19607 "%04u-%02u-%02uT%02u:%02u:%02u",
19608 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19609 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
19611 printf ("%3zu: ", cnt);
19612 if (valid_dynamic_name (filedata, liblist.l_name))
19613 print_symbol_name (20, get_dynamic_name (filedata, liblist.l_name));
19614 else
19615 printf (_("<corrupt: %9ld>"), liblist.l_name);
19616 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
19617 liblist.l_version);
19619 if (liblist.l_flags == 0)
19620 puts (_(" NONE"));
19621 else
19623 static const struct
19625 const char * name;
19626 int bit;
19628 l_flags_vals[] =
19630 { " EXACT_MATCH", LL_EXACT_MATCH },
19631 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
19632 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
19633 { " EXPORTS", LL_EXPORTS },
19634 { " DELAY_LOAD", LL_DELAY_LOAD },
19635 { " DELTA", LL_DELTA }
19637 int flags = liblist.l_flags;
19638 size_t fcnt;
19640 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
19641 if ((flags & l_flags_vals[fcnt].bit) != 0)
19643 fputs (l_flags_vals[fcnt].name, stdout);
19644 flags ^= l_flags_vals[fcnt].bit;
19646 if (flags != 0)
19647 printf (" %#x", (unsigned int) flags);
19649 puts ("");
19653 free (elib);
19655 else
19656 res = false;
19659 if (options_offset != 0)
19661 Elf_External_Options * eopt;
19662 size_t offset;
19663 int cnt;
19665 /* Find the section header so that we get the size. */
19666 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
19667 /* PR 17533 file: 012-277276-0.004. */
19668 if (sect == NULL)
19670 error (_("No MIPS_OPTIONS header found\n"));
19671 return false;
19673 /* PR 24243 */
19674 if (sect->sh_size < sizeof (* eopt))
19676 error (_("The MIPS options section is too small.\n"));
19677 return false;
19680 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
19681 sect->sh_size, _("options"));
19682 if (eopt)
19684 Elf_Internal_Options option;
19686 offset = cnt = 0;
19687 while (offset <= sect->sh_size - sizeof (* eopt))
19689 Elf_External_Options * eoption;
19690 unsigned int optsize;
19692 eoption = (Elf_External_Options *) ((char *) eopt + offset);
19694 optsize = BYTE_GET (eoption->size);
19696 /* PR 17531: file: ffa0fa3b. */
19697 if (optsize < sizeof (* eopt)
19698 || optsize > sect->sh_size - offset)
19700 error (_("Invalid size (%u) for MIPS option\n"),
19701 optsize);
19702 free (eopt);
19703 return false;
19705 offset += optsize;
19706 ++cnt;
19709 printf (ngettext ("\nSection '%s' contains %d entry:\n",
19710 "\nSection '%s' contains %d entries:\n",
19711 cnt),
19712 printable_section_name (filedata, sect), cnt);
19714 offset = 0;
19715 while (cnt-- > 0)
19717 size_t len;
19718 Elf_External_Options * eoption;
19720 eoption = (Elf_External_Options *) ((char *) eopt + offset);
19722 option.kind = BYTE_GET (eoption->kind);
19723 option.size = BYTE_GET (eoption->size);
19724 option.section = BYTE_GET (eoption->section);
19725 option.info = BYTE_GET (eoption->info);
19727 switch (option.kind)
19729 case ODK_NULL:
19730 /* This shouldn't happen. */
19731 printf (" NULL %" PRId16 " %" PRIx32,
19732 option.section, option.info);
19733 break;
19735 case ODK_REGINFO:
19736 printf (" REGINFO ");
19737 if (filedata->file_header.e_machine == EM_MIPS)
19739 Elf32_External_RegInfo * ereg;
19740 Elf32_RegInfo reginfo;
19742 /* 32bit form. */
19743 if (option.size < (sizeof (Elf_External_Options)
19744 + sizeof (Elf32_External_RegInfo)))
19746 printf (_("<corrupt>\n"));
19747 error (_("Truncated MIPS REGINFO option\n"));
19748 cnt = 0;
19749 break;
19752 ereg = (Elf32_External_RegInfo *) (eoption + 1);
19754 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
19755 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
19756 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
19757 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
19758 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
19759 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
19761 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
19762 reginfo.ri_gprmask, reginfo.ri_gp_value);
19763 printf (" "
19764 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
19765 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
19766 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
19767 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
19769 else
19771 /* 64 bit form. */
19772 Elf64_External_RegInfo * ereg;
19773 Elf64_Internal_RegInfo reginfo;
19775 if (option.size < (sizeof (Elf_External_Options)
19776 + sizeof (Elf64_External_RegInfo)))
19778 printf (_("<corrupt>\n"));
19779 error (_("Truncated MIPS REGINFO option\n"));
19780 cnt = 0;
19781 break;
19784 ereg = (Elf64_External_RegInfo *) (eoption + 1);
19785 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
19786 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
19787 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
19788 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
19789 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
19790 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
19792 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
19793 reginfo.ri_gprmask, reginfo.ri_gp_value);
19794 printf (" "
19795 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
19796 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
19797 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
19798 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
19800 offset += option.size;
19801 continue;
19803 case ODK_EXCEPTIONS:
19804 fputs (" EXCEPTIONS fpe_min(", stdout);
19805 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
19806 fputs (") fpe_max(", stdout);
19807 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
19808 fputs (")", stdout);
19810 if (option.info & OEX_PAGE0)
19811 fputs (" PAGE0", stdout);
19812 if (option.info & OEX_SMM)
19813 fputs (" SMM", stdout);
19814 if (option.info & OEX_FPDBUG)
19815 fputs (" FPDBUG", stdout);
19816 if (option.info & OEX_DISMISS)
19817 fputs (" DISMISS", stdout);
19818 break;
19820 case ODK_PAD:
19821 fputs (" PAD ", stdout);
19822 if (option.info & OPAD_PREFIX)
19823 fputs (" PREFIX", stdout);
19824 if (option.info & OPAD_POSTFIX)
19825 fputs (" POSTFIX", stdout);
19826 if (option.info & OPAD_SYMBOL)
19827 fputs (" SYMBOL", stdout);
19828 break;
19830 case ODK_HWPATCH:
19831 fputs (" HWPATCH ", stdout);
19832 if (option.info & OHW_R4KEOP)
19833 fputs (" R4KEOP", stdout);
19834 if (option.info & OHW_R8KPFETCH)
19835 fputs (" R8KPFETCH", stdout);
19836 if (option.info & OHW_R5KEOP)
19837 fputs (" R5KEOP", stdout);
19838 if (option.info & OHW_R5KCVTL)
19839 fputs (" R5KCVTL", stdout);
19840 break;
19842 case ODK_FILL:
19843 fputs (" FILL ", stdout);
19844 /* XXX Print content of info word? */
19845 break;
19847 case ODK_TAGS:
19848 fputs (" TAGS ", stdout);
19849 /* XXX Print content of info word? */
19850 break;
19852 case ODK_HWAND:
19853 fputs (" HWAND ", stdout);
19854 if (option.info & OHWA0_R4KEOP_CHECKED)
19855 fputs (" R4KEOP_CHECKED", stdout);
19856 if (option.info & OHWA0_R4KEOP_CLEAN)
19857 fputs (" R4KEOP_CLEAN", stdout);
19858 break;
19860 case ODK_HWOR:
19861 fputs (" HWOR ", stdout);
19862 if (option.info & OHWA0_R4KEOP_CHECKED)
19863 fputs (" R4KEOP_CHECKED", stdout);
19864 if (option.info & OHWA0_R4KEOP_CLEAN)
19865 fputs (" R4KEOP_CLEAN", stdout);
19866 break;
19868 case ODK_GP_GROUP:
19869 printf (" GP_GROUP %#06x self-contained %#06x",
19870 option.info & OGP_GROUP,
19871 (option.info & OGP_SELF) >> 16);
19872 break;
19874 case ODK_IDENT:
19875 printf (" IDENT %#06x self-contained %#06x",
19876 option.info & OGP_GROUP,
19877 (option.info & OGP_SELF) >> 16);
19878 break;
19880 default:
19881 /* This shouldn't happen. */
19882 printf (" %3d ??? %" PRId16 " %" PRIx32,
19883 option.kind, option.section, option.info);
19884 break;
19887 len = sizeof (* eopt);
19888 while (len < option.size)
19890 unsigned char datum = *((unsigned char *) eoption + len);
19892 if (ISPRINT (datum))
19893 printf ("%c", datum);
19894 else
19895 printf ("\\%03o", datum);
19896 len ++;
19898 fputs ("\n", stdout);
19900 offset += option.size;
19902 free (eopt);
19904 else
19905 res = false;
19908 if (conflicts_offset != 0 && conflictsno != 0)
19910 Elf32_Conflict * iconf;
19911 size_t cnt;
19913 if (filedata->dynamic_symbols == NULL)
19915 error (_("conflict list found without a dynamic symbol table\n"));
19916 return false;
19919 /* PR 21345 - print a slightly more helpful error message
19920 if we are sure that the cmalloc will fail. */
19921 if (conflictsno > filedata->file_size / sizeof (* iconf))
19923 error (_("Overlarge number of conflicts detected: %zx\n"),
19924 conflictsno);
19925 return false;
19928 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
19929 if (iconf == NULL)
19931 error (_("Out of memory allocating space for dynamic conflicts\n"));
19932 return false;
19935 if (is_32bit_elf)
19937 Elf32_External_Conflict * econf32;
19939 econf32 = (Elf32_External_Conflict *)
19940 get_data (NULL, filedata, conflicts_offset,
19941 sizeof (*econf32), conflictsno, _("conflict"));
19942 if (!econf32)
19944 free (iconf);
19945 return false;
19948 for (cnt = 0; cnt < conflictsno; ++cnt)
19949 iconf[cnt] = BYTE_GET (econf32[cnt]);
19951 free (econf32);
19953 else
19955 Elf64_External_Conflict * econf64;
19957 econf64 = (Elf64_External_Conflict *)
19958 get_data (NULL, filedata, conflicts_offset,
19959 sizeof (*econf64), conflictsno, _("conflict"));
19960 if (!econf64)
19962 free (iconf);
19963 return false;
19966 for (cnt = 0; cnt < conflictsno; ++cnt)
19967 iconf[cnt] = BYTE_GET (econf64[cnt]);
19969 free (econf64);
19972 printf (ngettext ("\nSection '.conflict' contains %zu entry:\n",
19973 "\nSection '.conflict' contains %zu entries:\n",
19974 conflictsno),
19975 conflictsno);
19976 puts (_(" Num: Index Value Name"));
19978 for (cnt = 0; cnt < conflictsno; ++cnt)
19980 printf ("%5zu: %8lu ", cnt, iconf[cnt]);
19982 if (iconf[cnt] >= filedata->num_dynamic_syms)
19983 printf (_("<corrupt symbol index>"));
19984 else
19986 Elf_Internal_Sym * psym;
19988 psym = & filedata->dynamic_symbols[iconf[cnt]];
19989 print_vma (psym->st_value, FULL_HEX);
19990 putchar (' ');
19991 if (valid_dynamic_name (filedata, psym->st_name))
19992 print_symbol_name (25, get_dynamic_name (filedata, psym->st_name));
19993 else
19994 printf (_("<corrupt: %14ld>"), psym->st_name);
19996 putchar ('\n');
19999 free (iconf);
20002 if (pltgot != 0 && local_gotno != 0)
20004 uint64_t ent, local_end, global_end;
20005 size_t i, offset;
20006 unsigned char * data;
20007 unsigned char * data_end;
20008 int addr_size;
20010 ent = pltgot;
20011 addr_size = (is_32bit_elf ? 4 : 8);
20012 local_end = pltgot + local_gotno * addr_size;
20014 /* PR binutils/17533 file: 012-111227-0.004 */
20015 if (symtabno < gotsym)
20017 error (_("The GOT symbol offset (%" PRIu64
20018 ") is greater than the symbol table size (%" PRIu64 ")\n"),
20019 gotsym, symtabno);
20020 return false;
20023 global_end = local_end + (symtabno - gotsym) * addr_size;
20024 /* PR 17531: file: 54c91a34. */
20025 if (global_end < local_end)
20027 error (_("Too many GOT symbols: %" PRIu64 "\n"), symtabno);
20028 return false;
20031 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
20032 data = (unsigned char *) get_data (NULL, filedata, offset,
20033 global_end - pltgot, 1,
20034 _("Global Offset Table data"));
20035 /* PR 12855: Null data is handled gracefully throughout. */
20036 data_end = data + (global_end - pltgot);
20038 printf (_("\nPrimary GOT:\n"));
20039 printf (_(" Canonical gp value: "));
20040 print_vma (pltgot + 0x7ff0, LONG_HEX);
20041 printf ("\n\n");
20043 printf (_(" Reserved entries:\n"));
20044 printf (_(" %*s %10s %*s Purpose\n"),
20045 addr_size * 2, _("Address"), _("Access"),
20046 addr_size * 2, _("Initial"));
20047 ent = print_mips_got_entry (data, pltgot, ent, data_end);
20048 printf (_(" Lazy resolver\n"));
20049 if (ent == (uint64_t) -1)
20050 goto got_print_fail;
20052 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
20053 This entry will be used by some runtime loaders, to store the
20054 module pointer. Otherwise this is an ordinary local entry.
20055 PR 21344: Check for the entry being fully available before
20056 fetching it. */
20057 if (data
20058 && data + ent - pltgot + addr_size <= data_end
20059 && (byte_get (data + ent - pltgot, addr_size)
20060 >> (addr_size * 8 - 1)) != 0)
20062 ent = print_mips_got_entry (data, pltgot, ent, data_end);
20063 printf (_(" Module pointer (GNU extension)\n"));
20064 if (ent == (uint64_t) -1)
20065 goto got_print_fail;
20067 printf ("\n");
20069 if (data != NULL && ent < local_end)
20071 printf (_(" Local entries:\n"));
20072 printf (" %*s %10s %*s\n",
20073 addr_size * 2, _("Address"), _("Access"),
20074 addr_size * 2, _("Initial"));
20075 while (ent < local_end)
20077 ent = print_mips_got_entry (data, pltgot, ent, data_end);
20078 printf ("\n");
20079 if (ent == (uint64_t) -1)
20080 goto got_print_fail;
20082 printf ("\n");
20085 if (data != NULL && gotsym < symtabno)
20087 int sym_width;
20089 printf (_(" Global entries:\n"));
20090 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
20091 addr_size * 2, _("Address"),
20092 _("Access"),
20093 addr_size * 2, _("Initial"),
20094 addr_size * 2, _("Sym.Val."),
20095 _("Type"),
20096 /* Note for translators: "Ndx" = abbreviated form of "Index". */
20097 _("Ndx"), _("Name"));
20099 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
20101 for (i = gotsym; i < symtabno; i++)
20103 ent = print_mips_got_entry (data, pltgot, ent, data_end);
20104 printf (" ");
20106 if (filedata->dynamic_symbols == NULL)
20107 printf (_("<no dynamic symbols>"));
20108 else if (i < filedata->num_dynamic_syms)
20110 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
20112 print_vma (psym->st_value, LONG_HEX);
20113 printf (" %-7s ", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
20115 bool is_special;
20116 const char * s = printable_section_name_from_index (filedata, psym->st_shndx, & is_special);
20117 if (is_special)
20118 printf ("%3s ", s);
20119 else
20120 printf ("%3u ", psym->st_shndx);
20122 if (valid_dynamic_name (filedata, psym->st_name))
20123 print_symbol_name (sym_width,
20124 get_dynamic_name (filedata, psym->st_name));
20125 else
20126 printf (_("<corrupt: %14ld>"), psym->st_name);
20128 else
20129 printf (_("<symbol index %zu exceeds number of dynamic symbols>"),
20132 printf ("\n");
20133 if (ent == (uint64_t) -1)
20134 break;
20136 printf ("\n");
20139 got_print_fail:
20140 free (data);
20143 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
20145 uint64_t ent, end;
20146 uint64_t offset, rel_offset;
20147 uint64_t count, i;
20148 unsigned char * data;
20149 int addr_size, sym_width;
20150 Elf_Internal_Rela * rels;
20152 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
20153 if (pltrel == DT_RELA)
20155 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
20156 return false;
20158 else
20160 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
20161 return false;
20164 ent = mips_pltgot;
20165 addr_size = (is_32bit_elf ? 4 : 8);
20166 end = mips_pltgot + (2 + count) * addr_size;
20168 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
20169 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
20170 1, _("Procedure Linkage Table data"));
20171 if (data == NULL)
20173 free (rels);
20174 return false;
20177 printf ("\nPLT GOT:\n\n");
20178 printf (_(" Reserved entries:\n"));
20179 printf (_(" %*s %*s Purpose\n"),
20180 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
20181 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
20182 printf (_(" PLT lazy resolver\n"));
20183 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
20184 printf (_(" Module pointer\n"));
20185 printf ("\n");
20187 printf (_(" Entries:\n"));
20188 printf (" %*s %*s %*s %-7s %3s %s\n",
20189 addr_size * 2, _("Address"),
20190 addr_size * 2, _("Initial"),
20191 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
20192 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
20193 for (i = 0; i < count; i++)
20195 uint64_t idx = get_reloc_symindex (rels[i].r_info);
20197 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
20198 printf (" ");
20200 if (idx >= filedata->num_dynamic_syms)
20201 printf (_("<corrupt symbol index: %" PRIu64 ">"), idx);
20202 else
20204 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
20206 print_vma (psym->st_value, LONG_HEX);
20207 printf (" %-7s %3s ",
20208 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
20209 printable_section_name_from_index (filedata, psym->st_shndx, NULL));
20210 if (valid_dynamic_name (filedata, psym->st_name))
20211 print_symbol_name (sym_width,
20212 get_dynamic_name (filedata, psym->st_name));
20213 else
20214 printf (_("<corrupt: %14ld>"), psym->st_name);
20216 printf ("\n");
20218 printf ("\n");
20220 free (data);
20221 free (rels);
20224 return res;
20227 static bool
20228 process_nds32_specific (Filedata * filedata)
20230 Elf_Internal_Shdr *sect = NULL;
20232 sect = find_section (filedata, ".nds32_e_flags");
20233 if (sect != NULL && sect->sh_size >= 4)
20235 unsigned char *buf;
20236 unsigned int flag;
20238 printf ("\nNDS32 elf flags section:\n");
20239 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
20240 _("NDS32 elf flags section"));
20242 if (buf == NULL)
20243 return false;
20245 flag = byte_get (buf, 4);
20246 free (buf);
20247 switch (flag & 0x3)
20249 case 0:
20250 printf ("(VEC_SIZE):\tNo entry.\n");
20251 break;
20252 case 1:
20253 printf ("(VEC_SIZE):\t4 bytes\n");
20254 break;
20255 case 2:
20256 printf ("(VEC_SIZE):\t16 bytes\n");
20257 break;
20258 case 3:
20259 printf ("(VEC_SIZE):\treserved\n");
20260 break;
20264 return true;
20267 static bool
20268 process_gnu_liblist (Filedata * filedata)
20270 Elf_Internal_Shdr * section;
20271 Elf_Internal_Shdr * string_sec;
20272 Elf32_External_Lib * elib;
20273 char * strtab;
20274 size_t strtab_size;
20275 size_t cnt;
20276 uint64_t num_liblist;
20277 unsigned i;
20278 bool res = true;
20280 if (! do_arch)
20281 return true;
20283 for (i = 0, section = filedata->section_headers;
20284 i < filedata->file_header.e_shnum;
20285 i++, section++)
20287 switch (section->sh_type)
20289 case SHT_GNU_LIBLIST:
20290 if (section->sh_link >= filedata->file_header.e_shnum)
20291 break;
20293 elib = (Elf32_External_Lib *)
20294 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
20295 _("liblist section data"));
20297 if (elib == NULL)
20299 res = false;
20300 break;
20303 string_sec = filedata->section_headers + section->sh_link;
20304 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
20305 string_sec->sh_size,
20306 _("liblist string table"));
20307 if (strtab == NULL
20308 || section->sh_entsize != sizeof (Elf32_External_Lib))
20310 free (elib);
20311 free (strtab);
20312 res = false;
20313 break;
20315 strtab_size = string_sec->sh_size;
20317 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
20318 printf (ngettext ("\nLibrary list section '%s' contains %" PRIu64
20319 " entries:\n",
20320 "\nLibrary list section '%s' contains %" PRIu64
20321 " entries:\n",
20322 num_liblist),
20323 printable_section_name (filedata, section),
20324 num_liblist);
20326 puts (_(" Library Time Stamp Checksum Version Flags"));
20328 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
20329 ++cnt)
20331 Elf32_Lib liblist;
20332 time_t atime;
20333 char timebuf[128];
20334 struct tm * tmp;
20336 liblist.l_name = BYTE_GET (elib[cnt].l_name);
20337 atime = BYTE_GET (elib[cnt].l_time_stamp);
20338 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
20339 liblist.l_version = BYTE_GET (elib[cnt].l_version);
20340 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
20342 tmp = gmtime (&atime);
20343 snprintf (timebuf, sizeof (timebuf),
20344 "%04u-%02u-%02uT%02u:%02u:%02u",
20345 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
20346 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
20348 printf ("%3zu: ", cnt);
20349 if (do_wide)
20350 printf ("%-20s", liblist.l_name < strtab_size
20351 ? strtab + liblist.l_name : _("<corrupt>"));
20352 else
20353 printf ("%-20.20s", liblist.l_name < strtab_size
20354 ? strtab + liblist.l_name : _("<corrupt>"));
20355 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
20356 liblist.l_version, liblist.l_flags);
20359 free (elib);
20360 free (strtab);
20364 return res;
20367 static const char *
20368 get_note_type (Filedata * filedata, unsigned e_type)
20370 static char buff[64];
20372 if (filedata->file_header.e_type == ET_CORE)
20373 switch (e_type)
20375 case NT_AUXV:
20376 return _("NT_AUXV (auxiliary vector)");
20377 case NT_PRSTATUS:
20378 return _("NT_PRSTATUS (prstatus structure)");
20379 case NT_FPREGSET:
20380 return _("NT_FPREGSET (floating point registers)");
20381 case NT_PRPSINFO:
20382 return _("NT_PRPSINFO (prpsinfo structure)");
20383 case NT_TASKSTRUCT:
20384 return _("NT_TASKSTRUCT (task structure)");
20385 case NT_GDB_TDESC:
20386 return _("NT_GDB_TDESC (GDB XML target description)");
20387 case NT_PRXFPREG:
20388 return _("NT_PRXFPREG (user_xfpregs structure)");
20389 case NT_PPC_VMX:
20390 return _("NT_PPC_VMX (ppc Altivec registers)");
20391 case NT_PPC_VSX:
20392 return _("NT_PPC_VSX (ppc VSX registers)");
20393 case NT_PPC_TAR:
20394 return _("NT_PPC_TAR (ppc TAR register)");
20395 case NT_PPC_PPR:
20396 return _("NT_PPC_PPR (ppc PPR register)");
20397 case NT_PPC_DSCR:
20398 return _("NT_PPC_DSCR (ppc DSCR register)");
20399 case NT_PPC_EBB:
20400 return _("NT_PPC_EBB (ppc EBB registers)");
20401 case NT_PPC_PMU:
20402 return _("NT_PPC_PMU (ppc PMU registers)");
20403 case NT_PPC_TM_CGPR:
20404 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
20405 case NT_PPC_TM_CFPR:
20406 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
20407 case NT_PPC_TM_CVMX:
20408 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
20409 case NT_PPC_TM_CVSX:
20410 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
20411 case NT_PPC_TM_SPR:
20412 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
20413 case NT_PPC_TM_CTAR:
20414 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
20415 case NT_PPC_TM_CPPR:
20416 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
20417 case NT_PPC_TM_CDSCR:
20418 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
20419 case NT_386_TLS:
20420 return _("NT_386_TLS (x86 TLS information)");
20421 case NT_386_IOPERM:
20422 return _("NT_386_IOPERM (x86 I/O permissions)");
20423 case NT_X86_XSTATE:
20424 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
20425 case NT_X86_CET:
20426 return _("NT_X86_CET (x86 CET state)");
20427 case NT_X86_SHSTK:
20428 return _("NT_X86_SHSTK (x86 SHSTK state)");
20429 case NT_S390_HIGH_GPRS:
20430 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
20431 case NT_S390_TIMER:
20432 return _("NT_S390_TIMER (s390 timer register)");
20433 case NT_S390_TODCMP:
20434 return _("NT_S390_TODCMP (s390 TOD comparator register)");
20435 case NT_S390_TODPREG:
20436 return _("NT_S390_TODPREG (s390 TOD programmable register)");
20437 case NT_S390_CTRS:
20438 return _("NT_S390_CTRS (s390 control registers)");
20439 case NT_S390_PREFIX:
20440 return _("NT_S390_PREFIX (s390 prefix register)");
20441 case NT_S390_LAST_BREAK:
20442 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
20443 case NT_S390_SYSTEM_CALL:
20444 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
20445 case NT_S390_TDB:
20446 return _("NT_S390_TDB (s390 transaction diagnostic block)");
20447 case NT_S390_VXRS_LOW:
20448 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
20449 case NT_S390_VXRS_HIGH:
20450 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
20451 case NT_S390_GS_CB:
20452 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
20453 case NT_S390_GS_BC:
20454 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
20455 case NT_ARM_VFP:
20456 return _("NT_ARM_VFP (arm VFP registers)");
20457 case NT_ARM_TLS:
20458 return _("NT_ARM_TLS (AArch TLS registers)");
20459 case NT_ARM_HW_BREAK:
20460 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
20461 case NT_ARM_HW_WATCH:
20462 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
20463 case NT_ARM_SYSTEM_CALL:
20464 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
20465 case NT_ARM_SVE:
20466 return _("NT_ARM_SVE (AArch SVE registers)");
20467 case NT_ARM_PAC_MASK:
20468 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
20469 case NT_ARM_PACA_KEYS:
20470 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
20471 case NT_ARM_PACG_KEYS:
20472 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
20473 case NT_ARM_TAGGED_ADDR_CTRL:
20474 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
20475 case NT_ARM_SSVE:
20476 return _("NT_ARM_SSVE (AArch64 streaming SVE registers)");
20477 case NT_ARM_ZA:
20478 return _("NT_ARM_ZA (AArch64 SME ZA register)");
20479 case NT_ARM_ZT:
20480 return _("NT_ARM_ZT (AArch64 SME2 ZT registers)");
20481 case NT_ARM_PAC_ENABLED_KEYS:
20482 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
20483 case NT_ARC_V2:
20484 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
20485 case NT_RISCV_CSR:
20486 return _("NT_RISCV_CSR (RISC-V control and status registers)");
20487 case NT_PSTATUS:
20488 return _("NT_PSTATUS (pstatus structure)");
20489 case NT_FPREGS:
20490 return _("NT_FPREGS (floating point registers)");
20491 case NT_PSINFO:
20492 return _("NT_PSINFO (psinfo structure)");
20493 case NT_LWPSTATUS:
20494 return _("NT_LWPSTATUS (lwpstatus_t structure)");
20495 case NT_LWPSINFO:
20496 return _("NT_LWPSINFO (lwpsinfo_t structure)");
20497 case NT_WIN32PSTATUS:
20498 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
20499 case NT_SIGINFO:
20500 return _("NT_SIGINFO (siginfo_t data)");
20501 case NT_FILE:
20502 return _("NT_FILE (mapped files)");
20503 default:
20504 break;
20506 else
20507 switch (e_type)
20509 case NT_VERSION:
20510 return _("NT_VERSION (version)");
20511 case NT_ARCH:
20512 return _("NT_ARCH (architecture)");
20513 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
20514 return _("OPEN");
20515 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
20516 return _("func");
20517 case NT_GO_BUILDID:
20518 return _("GO BUILDID");
20519 case FDO_PACKAGING_METADATA:
20520 return _("FDO_PACKAGING_METADATA");
20521 default:
20522 break;
20525 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20526 return buff;
20529 static bool
20530 print_core_note (Elf_Internal_Note *pnote)
20532 unsigned int addr_size = is_32bit_elf ? 4 : 8;
20533 uint64_t count, page_size;
20534 unsigned char *descdata, *filenames, *descend;
20536 if (pnote->type != NT_FILE)
20538 if (do_wide)
20539 printf ("\n");
20540 return true;
20543 if (pnote->descsz < 2 * addr_size)
20545 error (_(" Malformed note - too short for header\n"));
20546 return false;
20549 descdata = (unsigned char *) pnote->descdata;
20550 descend = descdata + pnote->descsz;
20552 if (descdata[pnote->descsz - 1] != '\0')
20554 error (_(" Malformed note - does not end with \\0\n"));
20555 return false;
20558 count = byte_get (descdata, addr_size);
20559 descdata += addr_size;
20561 page_size = byte_get (descdata, addr_size);
20562 descdata += addr_size;
20564 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
20565 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
20567 error (_(" Malformed note - too short for supplied file count\n"));
20568 return false;
20571 printf (_(" Page size: "));
20572 print_vma (page_size, DEC);
20573 printf ("\n");
20575 printf (_(" %*s%*s%*s\n"),
20576 (int) (2 + 2 * addr_size), _("Start"),
20577 (int) (4 + 2 * addr_size), _("End"),
20578 (int) (4 + 2 * addr_size), _("Page Offset"));
20579 filenames = descdata + count * 3 * addr_size;
20580 while (count-- > 0)
20582 uint64_t start, end, file_ofs;
20584 if (filenames == descend)
20586 error (_(" Malformed note - filenames end too early\n"));
20587 return false;
20590 start = byte_get (descdata, addr_size);
20591 descdata += addr_size;
20592 end = byte_get (descdata, addr_size);
20593 descdata += addr_size;
20594 file_ofs = byte_get (descdata, addr_size);
20595 descdata += addr_size;
20597 printf (" ");
20598 print_vma (start, FULL_HEX);
20599 printf (" ");
20600 print_vma (end, FULL_HEX);
20601 printf (" ");
20602 print_vma (file_ofs, FULL_HEX);
20603 printf ("\n %s\n", filenames);
20605 filenames += 1 + strlen ((char *) filenames);
20608 return true;
20611 static const char *
20612 get_gnu_elf_note_type (unsigned e_type)
20614 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
20615 switch (e_type)
20617 case NT_GNU_ABI_TAG:
20618 return _("NT_GNU_ABI_TAG (ABI version tag)");
20619 case NT_GNU_HWCAP:
20620 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
20621 case NT_GNU_BUILD_ID:
20622 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
20623 case NT_GNU_GOLD_VERSION:
20624 return _("NT_GNU_GOLD_VERSION (gold version)");
20625 case NT_GNU_PROPERTY_TYPE_0:
20626 return _("NT_GNU_PROPERTY_TYPE_0");
20627 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
20628 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
20629 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
20630 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
20631 default:
20633 static char buff[64];
20635 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20636 return buff;
20641 static void
20642 decode_x86_compat_isa (unsigned int bitmask)
20644 while (bitmask)
20646 unsigned int bit = bitmask & (- bitmask);
20648 bitmask &= ~ bit;
20649 switch (bit)
20651 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
20652 printf ("i486");
20653 break;
20654 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
20655 printf ("586");
20656 break;
20657 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
20658 printf ("686");
20659 break;
20660 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
20661 printf ("SSE");
20662 break;
20663 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
20664 printf ("SSE2");
20665 break;
20666 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
20667 printf ("SSE3");
20668 break;
20669 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
20670 printf ("SSSE3");
20671 break;
20672 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
20673 printf ("SSE4_1");
20674 break;
20675 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
20676 printf ("SSE4_2");
20677 break;
20678 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
20679 printf ("AVX");
20680 break;
20681 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
20682 printf ("AVX2");
20683 break;
20684 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
20685 printf ("AVX512F");
20686 break;
20687 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
20688 printf ("AVX512CD");
20689 break;
20690 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
20691 printf ("AVX512ER");
20692 break;
20693 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
20694 printf ("AVX512PF");
20695 break;
20696 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
20697 printf ("AVX512VL");
20698 break;
20699 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
20700 printf ("AVX512DQ");
20701 break;
20702 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
20703 printf ("AVX512BW");
20704 break;
20705 default:
20706 printf (_("<unknown: %x>"), bit);
20707 break;
20709 if (bitmask)
20710 printf (", ");
20714 static void
20715 decode_x86_compat_2_isa (unsigned int bitmask)
20717 if (!bitmask)
20719 printf (_("<None>"));
20720 return;
20723 while (bitmask)
20725 unsigned int bit = bitmask & (- bitmask);
20727 bitmask &= ~ bit;
20728 switch (bit)
20730 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
20731 printf ("CMOV");
20732 break;
20733 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
20734 printf ("SSE");
20735 break;
20736 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
20737 printf ("SSE2");
20738 break;
20739 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
20740 printf ("SSE3");
20741 break;
20742 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
20743 printf ("SSSE3");
20744 break;
20745 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
20746 printf ("SSE4_1");
20747 break;
20748 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
20749 printf ("SSE4_2");
20750 break;
20751 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
20752 printf ("AVX");
20753 break;
20754 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
20755 printf ("AVX2");
20756 break;
20757 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
20758 printf ("FMA");
20759 break;
20760 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
20761 printf ("AVX512F");
20762 break;
20763 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
20764 printf ("AVX512CD");
20765 break;
20766 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
20767 printf ("AVX512ER");
20768 break;
20769 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
20770 printf ("AVX512PF");
20771 break;
20772 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
20773 printf ("AVX512VL");
20774 break;
20775 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
20776 printf ("AVX512DQ");
20777 break;
20778 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
20779 printf ("AVX512BW");
20780 break;
20781 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
20782 printf ("AVX512_4FMAPS");
20783 break;
20784 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
20785 printf ("AVX512_4VNNIW");
20786 break;
20787 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
20788 printf ("AVX512_BITALG");
20789 break;
20790 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
20791 printf ("AVX512_IFMA");
20792 break;
20793 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
20794 printf ("AVX512_VBMI");
20795 break;
20796 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
20797 printf ("AVX512_VBMI2");
20798 break;
20799 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
20800 printf ("AVX512_VNNI");
20801 break;
20802 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
20803 printf ("AVX512_BF16");
20804 break;
20805 default:
20806 printf (_("<unknown: %x>"), bit);
20807 break;
20809 if (bitmask)
20810 printf (", ");
20814 static const char *
20815 get_amdgpu_elf_note_type (unsigned int e_type)
20817 switch (e_type)
20819 case NT_AMDGPU_METADATA:
20820 return _("NT_AMDGPU_METADATA (code object metadata)");
20821 default:
20823 static char buf[64];
20824 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
20825 return buf;
20830 static void
20831 decode_x86_isa (unsigned int bitmask)
20833 while (bitmask)
20835 unsigned int bit = bitmask & (- bitmask);
20837 bitmask &= ~ bit;
20838 switch (bit)
20840 case GNU_PROPERTY_X86_ISA_1_BASELINE:
20841 printf ("x86-64-baseline");
20842 break;
20843 case GNU_PROPERTY_X86_ISA_1_V2:
20844 printf ("x86-64-v2");
20845 break;
20846 case GNU_PROPERTY_X86_ISA_1_V3:
20847 printf ("x86-64-v3");
20848 break;
20849 case GNU_PROPERTY_X86_ISA_1_V4:
20850 printf ("x86-64-v4");
20851 break;
20852 default:
20853 printf (_("<unknown: %x>"), bit);
20854 break;
20856 if (bitmask)
20857 printf (", ");
20861 static void
20862 decode_x86_feature_1 (unsigned int bitmask)
20864 if (!bitmask)
20866 printf (_("<None>"));
20867 return;
20870 while (bitmask)
20872 unsigned int bit = bitmask & (- bitmask);
20874 bitmask &= ~ bit;
20875 switch (bit)
20877 case GNU_PROPERTY_X86_FEATURE_1_IBT:
20878 printf ("IBT");
20879 break;
20880 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
20881 printf ("SHSTK");
20882 break;
20883 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
20884 printf ("LAM_U48");
20885 break;
20886 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
20887 printf ("LAM_U57");
20888 break;
20889 default:
20890 printf (_("<unknown: %x>"), bit);
20891 break;
20893 if (bitmask)
20894 printf (", ");
20898 static void
20899 decode_x86_feature_2 (unsigned int bitmask)
20901 if (!bitmask)
20903 printf (_("<None>"));
20904 return;
20907 while (bitmask)
20909 unsigned int bit = bitmask & (- bitmask);
20911 bitmask &= ~ bit;
20912 switch (bit)
20914 case GNU_PROPERTY_X86_FEATURE_2_X86:
20915 printf ("x86");
20916 break;
20917 case GNU_PROPERTY_X86_FEATURE_2_X87:
20918 printf ("x87");
20919 break;
20920 case GNU_PROPERTY_X86_FEATURE_2_MMX:
20921 printf ("MMX");
20922 break;
20923 case GNU_PROPERTY_X86_FEATURE_2_XMM:
20924 printf ("XMM");
20925 break;
20926 case GNU_PROPERTY_X86_FEATURE_2_YMM:
20927 printf ("YMM");
20928 break;
20929 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
20930 printf ("ZMM");
20931 break;
20932 case GNU_PROPERTY_X86_FEATURE_2_TMM:
20933 printf ("TMM");
20934 break;
20935 case GNU_PROPERTY_X86_FEATURE_2_MASK:
20936 printf ("MASK");
20937 break;
20938 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
20939 printf ("FXSR");
20940 break;
20941 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
20942 printf ("XSAVE");
20943 break;
20944 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
20945 printf ("XSAVEOPT");
20946 break;
20947 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
20948 printf ("XSAVEC");
20949 break;
20950 default:
20951 printf (_("<unknown: %x>"), bit);
20952 break;
20954 if (bitmask)
20955 printf (", ");
20959 static void
20960 decode_aarch64_feature_1_and (unsigned int bitmask)
20962 while (bitmask)
20964 unsigned int bit = bitmask & (- bitmask);
20966 bitmask &= ~ bit;
20967 switch (bit)
20969 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
20970 printf ("BTI");
20971 break;
20973 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
20974 printf ("PAC");
20975 break;
20977 default:
20978 printf (_("<unknown: %x>"), bit);
20979 break;
20981 if (bitmask)
20982 printf (", ");
20986 static void
20987 decode_1_needed (unsigned int bitmask)
20989 while (bitmask)
20991 unsigned int bit = bitmask & (- bitmask);
20993 bitmask &= ~ bit;
20994 switch (bit)
20996 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
20997 printf ("indirect external access");
20998 break;
20999 default:
21000 printf (_("<unknown: %x>"), bit);
21001 break;
21003 if (bitmask)
21004 printf (", ");
21008 static void
21009 print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
21011 unsigned char * ptr = (unsigned char *) pnote->descdata;
21012 unsigned char * ptr_end = ptr + pnote->descsz;
21013 unsigned int size = is_32bit_elf ? 4 : 8;
21015 printf (_(" Properties: "));
21017 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
21019 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
21020 return;
21023 while (ptr < ptr_end)
21025 unsigned int j;
21026 unsigned int type;
21027 unsigned int datasz;
21029 if ((size_t) (ptr_end - ptr) < 8)
21031 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
21032 break;
21035 type = byte_get (ptr, 4);
21036 datasz = byte_get (ptr + 4, 4);
21038 ptr += 8;
21040 if (datasz > (size_t) (ptr_end - ptr))
21042 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
21043 type, datasz);
21044 break;
21047 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
21049 if (filedata->file_header.e_machine == EM_X86_64
21050 || filedata->file_header.e_machine == EM_IAMCU
21051 || filedata->file_header.e_machine == EM_386)
21053 unsigned int bitmask;
21055 if (datasz == 4)
21056 bitmask = byte_get (ptr, 4);
21057 else
21058 bitmask = 0;
21060 switch (type)
21062 case GNU_PROPERTY_X86_ISA_1_USED:
21063 if (datasz != 4)
21064 printf (_("x86 ISA used: <corrupt length: %#x> "),
21065 datasz);
21066 else
21068 printf ("x86 ISA used: ");
21069 decode_x86_isa (bitmask);
21071 goto next;
21073 case GNU_PROPERTY_X86_ISA_1_NEEDED:
21074 if (datasz != 4)
21075 printf (_("x86 ISA needed: <corrupt length: %#x> "),
21076 datasz);
21077 else
21079 printf ("x86 ISA needed: ");
21080 decode_x86_isa (bitmask);
21082 goto next;
21084 case GNU_PROPERTY_X86_FEATURE_1_AND:
21085 if (datasz != 4)
21086 printf (_("x86 feature: <corrupt length: %#x> "),
21087 datasz);
21088 else
21090 printf ("x86 feature: ");
21091 decode_x86_feature_1 (bitmask);
21093 goto next;
21095 case GNU_PROPERTY_X86_FEATURE_2_USED:
21096 if (datasz != 4)
21097 printf (_("x86 feature used: <corrupt length: %#x> "),
21098 datasz);
21099 else
21101 printf ("x86 feature used: ");
21102 decode_x86_feature_2 (bitmask);
21104 goto next;
21106 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
21107 if (datasz != 4)
21108 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
21109 else
21111 printf ("x86 feature needed: ");
21112 decode_x86_feature_2 (bitmask);
21114 goto next;
21116 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
21117 if (datasz != 4)
21118 printf (_("x86 ISA used: <corrupt length: %#x> "),
21119 datasz);
21120 else
21122 printf ("x86 ISA used: ");
21123 decode_x86_compat_isa (bitmask);
21125 goto next;
21127 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
21128 if (datasz != 4)
21129 printf (_("x86 ISA needed: <corrupt length: %#x> "),
21130 datasz);
21131 else
21133 printf ("x86 ISA needed: ");
21134 decode_x86_compat_isa (bitmask);
21136 goto next;
21138 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
21139 if (datasz != 4)
21140 printf (_("x86 ISA used: <corrupt length: %#x> "),
21141 datasz);
21142 else
21144 printf ("x86 ISA used: ");
21145 decode_x86_compat_2_isa (bitmask);
21147 goto next;
21149 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
21150 if (datasz != 4)
21151 printf (_("x86 ISA needed: <corrupt length: %#x> "),
21152 datasz);
21153 else
21155 printf ("x86 ISA needed: ");
21156 decode_x86_compat_2_isa (bitmask);
21158 goto next;
21160 default:
21161 break;
21164 else if (filedata->file_header.e_machine == EM_AARCH64)
21166 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
21168 printf ("AArch64 feature: ");
21169 if (datasz != 4)
21170 printf (_("<corrupt length: %#x> "), datasz);
21171 else
21172 decode_aarch64_feature_1_and (byte_get (ptr, 4));
21173 goto next;
21177 else
21179 switch (type)
21181 case GNU_PROPERTY_STACK_SIZE:
21182 printf (_("stack size: "));
21183 if (datasz != size)
21184 printf (_("<corrupt length: %#x> "), datasz);
21185 else
21186 printf ("%#" PRIx64, byte_get (ptr, size));
21187 goto next;
21189 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
21190 printf ("no copy on protected ");
21191 if (datasz)
21192 printf (_("<corrupt length: %#x> "), datasz);
21193 goto next;
21195 default:
21196 if ((type >= GNU_PROPERTY_UINT32_AND_LO
21197 && type <= GNU_PROPERTY_UINT32_AND_HI)
21198 || (type >= GNU_PROPERTY_UINT32_OR_LO
21199 && type <= GNU_PROPERTY_UINT32_OR_HI))
21201 switch (type)
21203 case GNU_PROPERTY_1_NEEDED:
21204 if (datasz != 4)
21205 printf (_("1_needed: <corrupt length: %#x> "),
21206 datasz);
21207 else
21209 unsigned int bitmask = byte_get (ptr, 4);
21210 printf ("1_needed: ");
21211 decode_1_needed (bitmask);
21213 goto next;
21215 default:
21216 break;
21218 if (type <= GNU_PROPERTY_UINT32_AND_HI)
21219 printf (_("UINT32_AND (%#x): "), type);
21220 else
21221 printf (_("UINT32_OR (%#x): "), type);
21222 if (datasz != 4)
21223 printf (_("<corrupt length: %#x> "), datasz);
21224 else
21225 printf ("%#x", (unsigned int) byte_get (ptr, 4));
21226 goto next;
21228 break;
21232 if (type < GNU_PROPERTY_LOPROC)
21233 printf (_("<unknown type %#x data: "), type);
21234 else if (type < GNU_PROPERTY_LOUSER)
21235 printf (_("<processor-specific type %#x data: "), type);
21236 else
21237 printf (_("<application-specific type %#x data: "), type);
21238 for (j = 0; j < datasz; ++j)
21239 printf ("%02x ", ptr[j] & 0xff);
21240 printf (">");
21242 next:
21243 ptr += ((datasz + (size - 1)) & ~ (size - 1));
21244 if (ptr == ptr_end)
21245 break;
21247 if (do_wide)
21248 printf (", ");
21249 else
21250 printf ("\n\t");
21253 printf ("\n");
21256 static bool
21257 print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
21259 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
21260 switch (pnote->type)
21262 case NT_GNU_BUILD_ID:
21264 size_t i;
21266 printf (_(" Build ID: "));
21267 for (i = 0; i < pnote->descsz; ++i)
21268 printf ("%02x", pnote->descdata[i] & 0xff);
21269 printf ("\n");
21271 break;
21273 case NT_GNU_ABI_TAG:
21275 unsigned int os, major, minor, subminor;
21276 const char *osname;
21278 /* PR 17531: file: 030-599401-0.004. */
21279 if (pnote->descsz < 16)
21281 printf (_(" <corrupt GNU_ABI_TAG>\n"));
21282 break;
21285 os = byte_get ((unsigned char *) pnote->descdata, 4);
21286 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
21287 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
21288 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
21290 switch (os)
21292 case GNU_ABI_TAG_LINUX:
21293 osname = "Linux";
21294 break;
21295 case GNU_ABI_TAG_HURD:
21296 osname = "Hurd";
21297 break;
21298 case GNU_ABI_TAG_SOLARIS:
21299 osname = "Solaris";
21300 break;
21301 case GNU_ABI_TAG_FREEBSD:
21302 osname = "FreeBSD";
21303 break;
21304 case GNU_ABI_TAG_NETBSD:
21305 osname = "NetBSD";
21306 break;
21307 case GNU_ABI_TAG_SYLLABLE:
21308 osname = "Syllable";
21309 break;
21310 case GNU_ABI_TAG_NACL:
21311 osname = "NaCl";
21312 break;
21313 default:
21314 osname = "Unknown";
21315 break;
21318 printf (_(" OS: %s, ABI: %d.%d.%d\n"), osname,
21319 major, minor, subminor);
21321 break;
21323 case NT_GNU_GOLD_VERSION:
21325 size_t i;
21327 printf (_(" Version: "));
21328 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
21329 printf ("%c", pnote->descdata[i]);
21330 printf ("\n");
21332 break;
21334 case NT_GNU_HWCAP:
21336 unsigned int num_entries, mask;
21338 /* Hardware capabilities information. Word 0 is the number of entries.
21339 Word 1 is a bitmask of enabled entries. The rest of the descriptor
21340 is a series of entries, where each entry is a single byte followed
21341 by a nul terminated string. The byte gives the bit number to test
21342 if enabled in the bitmask. */
21343 printf (_(" Hardware Capabilities: "));
21344 if (pnote->descsz < 8)
21346 error (_("<corrupt GNU_HWCAP>\n"));
21347 return false;
21349 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
21350 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
21351 printf (_("num entries: %d, enabled mask: %x\n"), num_entries, mask);
21352 /* FIXME: Add code to display the entries... */
21354 break;
21356 case NT_GNU_PROPERTY_TYPE_0:
21357 print_gnu_property_note (filedata, pnote);
21358 break;
21360 default:
21361 /* Handle unrecognised types. An error message should have already been
21362 created by get_gnu_elf_note_type(), so all that we need to do is to
21363 display the data. */
21365 size_t i;
21367 printf (_(" Description data: "));
21368 for (i = 0; i < pnote->descsz; ++i)
21369 printf ("%02x ", pnote->descdata[i] & 0xff);
21370 printf ("\n");
21372 break;
21375 return true;
21378 static const char *
21379 get_v850_elf_note_type (enum v850_notes n_type)
21381 static char buff[64];
21383 switch (n_type)
21385 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
21386 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
21387 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
21388 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
21389 case V850_NOTE_CACHE_INFO: return _("Use of cache");
21390 case V850_NOTE_MMU_INFO: return _("Use of MMU");
21391 default:
21392 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
21393 return buff;
21397 static bool
21398 print_v850_note (Elf_Internal_Note * pnote)
21400 unsigned int val;
21402 if (pnote->descsz != 4)
21403 return false;
21405 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
21407 if (val == 0)
21409 printf (_("not set\n"));
21410 return true;
21413 switch (pnote->type)
21415 case V850_NOTE_ALIGNMENT:
21416 switch (val)
21418 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
21419 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
21421 break;
21423 case V850_NOTE_DATA_SIZE:
21424 switch (val)
21426 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
21427 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
21429 break;
21431 case V850_NOTE_FPU_INFO:
21432 switch (val)
21434 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
21435 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
21437 break;
21439 case V850_NOTE_MMU_INFO:
21440 case V850_NOTE_CACHE_INFO:
21441 case V850_NOTE_SIMD_INFO:
21442 if (val == EF_RH850_SIMD)
21444 printf (_("yes\n"));
21445 return true;
21447 break;
21449 default:
21450 /* An 'unknown note type' message will already have been displayed. */
21451 break;
21454 printf (_("unknown value: %x\n"), val);
21455 return false;
21458 static bool
21459 process_netbsd_elf_note (Elf_Internal_Note * pnote)
21461 unsigned int version;
21463 switch (pnote->type)
21465 case NT_NETBSD_IDENT:
21466 if (pnote->descsz < 1)
21467 break;
21468 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21469 if ((version / 10000) % 100)
21470 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
21471 version, version / 100000000, (version / 1000000) % 100,
21472 (version / 10000) % 100 > 26 ? "Z" : "",
21473 'A' + (version / 10000) % 26);
21474 else
21475 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
21476 version, version / 100000000, (version / 1000000) % 100,
21477 (version / 100) % 100);
21478 return true;
21480 case NT_NETBSD_MARCH:
21481 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
21482 pnote->descdata);
21483 return true;
21485 case NT_NETBSD_PAX:
21486 if (pnote->descsz < 1)
21487 break;
21488 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21489 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
21490 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
21491 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
21492 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
21493 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
21494 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
21495 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
21496 return true;
21499 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
21500 pnote->descsz, pnote->type);
21501 return false;
21504 static const char *
21505 get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
21507 switch (e_type)
21509 case NT_FREEBSD_THRMISC:
21510 return _("NT_THRMISC (thrmisc structure)");
21511 case NT_FREEBSD_PROCSTAT_PROC:
21512 return _("NT_PROCSTAT_PROC (proc data)");
21513 case NT_FREEBSD_PROCSTAT_FILES:
21514 return _("NT_PROCSTAT_FILES (files data)");
21515 case NT_FREEBSD_PROCSTAT_VMMAP:
21516 return _("NT_PROCSTAT_VMMAP (vmmap data)");
21517 case NT_FREEBSD_PROCSTAT_GROUPS:
21518 return _("NT_PROCSTAT_GROUPS (groups data)");
21519 case NT_FREEBSD_PROCSTAT_UMASK:
21520 return _("NT_PROCSTAT_UMASK (umask data)");
21521 case NT_FREEBSD_PROCSTAT_RLIMIT:
21522 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
21523 case NT_FREEBSD_PROCSTAT_OSREL:
21524 return _("NT_PROCSTAT_OSREL (osreldate data)");
21525 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
21526 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
21527 case NT_FREEBSD_PROCSTAT_AUXV:
21528 return _("NT_PROCSTAT_AUXV (auxv data)");
21529 case NT_FREEBSD_PTLWPINFO:
21530 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
21531 case NT_FREEBSD_X86_SEGBASES:
21532 return _("NT_X86_SEGBASES (x86 segment base registers)");
21534 return get_note_type (filedata, e_type);
21537 static const char *
21538 get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
21540 static char buff[64];
21542 switch (e_type)
21544 case NT_NETBSDCORE_PROCINFO:
21545 /* NetBSD core "procinfo" structure. */
21546 return _("NetBSD procinfo structure");
21548 case NT_NETBSDCORE_AUXV:
21549 return _("NetBSD ELF auxiliary vector data");
21551 case NT_NETBSDCORE_LWPSTATUS:
21552 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
21554 default:
21555 /* As of Jan 2020 there are no other machine-independent notes
21556 defined for NetBSD core files. If the note type is less
21557 than the start of the machine-dependent note types, we don't
21558 understand it. */
21560 if (e_type < NT_NETBSDCORE_FIRSTMACH)
21562 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21563 return buff;
21565 break;
21568 switch (filedata->file_header.e_machine)
21570 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
21571 and PT_GETFPREGS == mach+2. */
21573 case EM_OLD_ALPHA:
21574 case EM_ALPHA:
21575 case EM_SPARC:
21576 case EM_SPARC32PLUS:
21577 case EM_SPARCV9:
21578 switch (e_type)
21580 case NT_NETBSDCORE_FIRSTMACH + 0:
21581 return _("PT_GETREGS (reg structure)");
21582 case NT_NETBSDCORE_FIRSTMACH + 2:
21583 return _("PT_GETFPREGS (fpreg structure)");
21584 default:
21585 break;
21587 break;
21589 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
21590 There's also old PT___GETREGS40 == mach + 1 for old reg
21591 structure which lacks GBR. */
21592 case EM_SH:
21593 switch (e_type)
21595 case NT_NETBSDCORE_FIRSTMACH + 1:
21596 return _("PT___GETREGS40 (old reg structure)");
21597 case NT_NETBSDCORE_FIRSTMACH + 3:
21598 return _("PT_GETREGS (reg structure)");
21599 case NT_NETBSDCORE_FIRSTMACH + 5:
21600 return _("PT_GETFPREGS (fpreg structure)");
21601 default:
21602 break;
21604 break;
21606 /* On all other arch's, PT_GETREGS == mach+1 and
21607 PT_GETFPREGS == mach+3. */
21608 default:
21609 switch (e_type)
21611 case NT_NETBSDCORE_FIRSTMACH + 1:
21612 return _("PT_GETREGS (reg structure)");
21613 case NT_NETBSDCORE_FIRSTMACH + 3:
21614 return _("PT_GETFPREGS (fpreg structure)");
21615 default:
21616 break;
21620 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
21621 e_type - NT_NETBSDCORE_FIRSTMACH);
21622 return buff;
21625 static const char *
21626 get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
21628 switch (e_type)
21630 case NT_OPENBSD_PROCINFO:
21631 return _("OpenBSD procinfo structure");
21632 case NT_OPENBSD_AUXV:
21633 return _("OpenBSD ELF auxiliary vector data");
21634 case NT_OPENBSD_REGS:
21635 return _("OpenBSD regular registers");
21636 case NT_OPENBSD_FPREGS:
21637 return _("OpenBSD floating point registers");
21638 case NT_OPENBSD_WCOOKIE:
21639 return _("OpenBSD window cookie");
21642 return get_note_type (filedata, e_type);
21645 static const char *
21646 get_qnx_elfcore_note_type (Filedata * filedata, unsigned e_type)
21648 switch (e_type)
21650 case QNT_DEBUG_FULLPATH:
21651 return _("QNX debug fullpath");
21652 case QNT_DEBUG_RELOC:
21653 return _("QNX debug relocation");
21654 case QNT_STACK:
21655 return _("QNX stack");
21656 case QNT_GENERATOR:
21657 return _("QNX generator");
21658 case QNT_DEFAULT_LIB:
21659 return _("QNX default library");
21660 case QNT_CORE_SYSINFO:
21661 return _("QNX core sysinfo");
21662 case QNT_CORE_INFO:
21663 return _("QNX core info");
21664 case QNT_CORE_STATUS:
21665 return _("QNX core status");
21666 case QNT_CORE_GREG:
21667 return _("QNX general registers");
21668 case QNT_CORE_FPREG:
21669 return _("QNX floating point registers");
21670 case QNT_LINK_MAP:
21671 return _("QNX link map");
21674 return get_note_type (filedata, e_type);
21677 static const char *
21678 get_stapsdt_note_type (unsigned e_type)
21680 static char buff[64];
21682 switch (e_type)
21684 case NT_STAPSDT:
21685 return _("NT_STAPSDT (SystemTap probe descriptors)");
21687 default:
21688 break;
21691 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21692 return buff;
21695 static bool
21696 print_stapsdt_note (Elf_Internal_Note *pnote)
21698 size_t len, maxlen;
21699 size_t addr_size = is_32bit_elf ? 4 : 8;
21700 char *data = pnote->descdata;
21701 char *data_end = pnote->descdata + pnote->descsz;
21702 uint64_t pc, base_addr, semaphore;
21703 char *provider, *probe, *arg_fmt;
21705 if (pnote->descsz < (addr_size * 3))
21706 goto stapdt_note_too_small;
21708 pc = byte_get ((unsigned char *) data, addr_size);
21709 data += addr_size;
21711 base_addr = byte_get ((unsigned char *) data, addr_size);
21712 data += addr_size;
21714 semaphore = byte_get ((unsigned char *) data, addr_size);
21715 data += addr_size;
21717 if (data >= data_end)
21718 goto stapdt_note_too_small;
21719 maxlen = data_end - data;
21720 len = strnlen (data, maxlen);
21721 if (len < maxlen)
21723 provider = data;
21724 data += len + 1;
21726 else
21727 goto stapdt_note_too_small;
21729 if (data >= data_end)
21730 goto stapdt_note_too_small;
21731 maxlen = data_end - data;
21732 len = strnlen (data, maxlen);
21733 if (len < maxlen)
21735 probe = data;
21736 data += len + 1;
21738 else
21739 goto stapdt_note_too_small;
21741 if (data >= data_end)
21742 goto stapdt_note_too_small;
21743 maxlen = data_end - data;
21744 len = strnlen (data, maxlen);
21745 if (len < maxlen)
21747 arg_fmt = data;
21748 data += len + 1;
21750 else
21751 goto stapdt_note_too_small;
21753 printf (_(" Provider: %s\n"), provider);
21754 printf (_(" Name: %s\n"), probe);
21755 printf (_(" Location: "));
21756 print_vma (pc, FULL_HEX);
21757 printf (_(", Base: "));
21758 print_vma (base_addr, FULL_HEX);
21759 printf (_(", Semaphore: "));
21760 print_vma (semaphore, FULL_HEX);
21761 printf ("\n");
21762 printf (_(" Arguments: %s\n"), arg_fmt);
21764 return data == data_end;
21766 stapdt_note_too_small:
21767 printf (_(" <corrupt - note is too small>\n"));
21768 error (_("corrupt stapdt note - the data size is too small\n"));
21769 return false;
21772 static bool
21773 print_fdo_note (Elf_Internal_Note * pnote)
21775 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
21777 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
21778 return true;
21780 return false;
21783 static const char *
21784 get_ia64_vms_note_type (unsigned e_type)
21786 static char buff[64];
21788 switch (e_type)
21790 case NT_VMS_MHD:
21791 return _("NT_VMS_MHD (module header)");
21792 case NT_VMS_LNM:
21793 return _("NT_VMS_LNM (language name)");
21794 case NT_VMS_SRC:
21795 return _("NT_VMS_SRC (source files)");
21796 case NT_VMS_TITLE:
21797 return "NT_VMS_TITLE";
21798 case NT_VMS_EIDC:
21799 return _("NT_VMS_EIDC (consistency check)");
21800 case NT_VMS_FPMODE:
21801 return _("NT_VMS_FPMODE (FP mode)");
21802 case NT_VMS_LINKTIME:
21803 return "NT_VMS_LINKTIME";
21804 case NT_VMS_IMGNAM:
21805 return _("NT_VMS_IMGNAM (image name)");
21806 case NT_VMS_IMGID:
21807 return _("NT_VMS_IMGID (image id)");
21808 case NT_VMS_LINKID:
21809 return _("NT_VMS_LINKID (link id)");
21810 case NT_VMS_IMGBID:
21811 return _("NT_VMS_IMGBID (build id)");
21812 case NT_VMS_GSTNAM:
21813 return _("NT_VMS_GSTNAM (sym table name)");
21814 case NT_VMS_ORIG_DYN:
21815 return "NT_VMS_ORIG_DYN";
21816 case NT_VMS_PATCHTIME:
21817 return "NT_VMS_PATCHTIME";
21818 default:
21819 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21820 return buff;
21824 static bool
21825 print_ia64_vms_note (Elf_Internal_Note * pnote)
21827 unsigned int maxlen = pnote->descsz;
21829 if (maxlen < 2 || maxlen != pnote->descsz)
21830 goto desc_size_fail;
21832 switch (pnote->type)
21834 case NT_VMS_MHD:
21835 if (maxlen <= 36)
21836 goto desc_size_fail;
21838 size_t l = strnlen (pnote->descdata + 34, maxlen - 34);
21840 printf (_(" Creation date : %.17s\n"), pnote->descdata);
21841 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
21842 if (l + 34 < maxlen)
21844 printf (_(" Module name : %s\n"), pnote->descdata + 34);
21845 if (l + 35 < maxlen)
21846 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
21847 else
21848 printf (_(" Module version : <missing>\n"));
21850 else
21852 printf (_(" Module name : <missing>\n"));
21853 printf (_(" Module version : <missing>\n"));
21855 break;
21857 case NT_VMS_LNM:
21858 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
21859 break;
21861 case NT_VMS_FPMODE:
21862 printf (_(" Floating Point mode: "));
21863 if (maxlen < 8)
21864 goto desc_size_fail;
21865 /* FIXME: Generate an error if descsz > 8 ? */
21867 printf ("0x%016" PRIx64 "\n",
21868 byte_get ((unsigned char *) pnote->descdata, 8));
21869 break;
21871 case NT_VMS_LINKTIME:
21872 printf (_(" Link time: "));
21873 if (maxlen < 8)
21874 goto desc_size_fail;
21875 /* FIXME: Generate an error if descsz > 8 ? */
21877 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
21878 printf ("\n");
21879 break;
21881 case NT_VMS_PATCHTIME:
21882 printf (_(" Patch time: "));
21883 if (maxlen < 8)
21884 goto desc_size_fail;
21885 /* FIXME: Generate an error if descsz > 8 ? */
21887 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
21888 printf ("\n");
21889 break;
21891 case NT_VMS_ORIG_DYN:
21892 if (maxlen < 34)
21893 goto desc_size_fail;
21895 printf (_(" Major id: %u, minor id: %u\n"),
21896 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
21897 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
21898 printf (_(" Last modified : "));
21899 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
21900 printf (_("\n Link flags : "));
21901 printf ("0x%016" PRIx64 "\n",
21902 byte_get ((unsigned char *) pnote->descdata + 16, 8));
21903 printf (_(" Header flags: 0x%08x\n"),
21904 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
21905 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
21906 break;
21908 case NT_VMS_IMGNAM:
21909 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
21910 break;
21912 case NT_VMS_GSTNAM:
21913 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
21914 break;
21916 case NT_VMS_IMGID:
21917 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
21918 break;
21920 case NT_VMS_LINKID:
21921 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
21922 break;
21924 default:
21925 return false;
21928 return true;
21930 desc_size_fail:
21931 printf (_(" <corrupt - data size is too small>\n"));
21932 error (_("corrupt IA64 note: data size is too small\n"));
21933 return false;
21936 struct build_attr_cache {
21937 Filedata *filedata;
21938 char *strtab;
21939 uint64_t strtablen;
21940 Elf_Internal_Sym *symtab;
21941 uint64_t nsyms;
21942 } ba_cache;
21944 /* Find the symbol associated with a build attribute that is attached
21945 to address OFFSET. If PNAME is non-NULL then store the name of
21946 the symbol (if found) in the provided pointer, Returns NULL if a
21947 symbol could not be found. */
21949 static Elf_Internal_Sym *
21950 get_symbol_for_build_attribute (Filedata *filedata,
21951 uint64_t offset,
21952 bool is_open_attr,
21953 const char **pname)
21955 Elf_Internal_Sym *saved_sym = NULL;
21956 Elf_Internal_Sym *sym;
21958 if (filedata->section_headers != NULL
21959 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
21961 Elf_Internal_Shdr * symsec;
21963 free (ba_cache.strtab);
21964 ba_cache.strtab = NULL;
21965 free (ba_cache.symtab);
21966 ba_cache.symtab = NULL;
21968 /* Load the symbol and string sections. */
21969 for (symsec = filedata->section_headers;
21970 symsec < filedata->section_headers + filedata->file_header.e_shnum;
21971 symsec ++)
21973 if (symsec->sh_type == SHT_SYMTAB
21974 && get_symtab (filedata, symsec,
21975 &ba_cache.symtab, &ba_cache.nsyms,
21976 &ba_cache.strtab, &ba_cache.strtablen))
21977 break;
21979 ba_cache.filedata = filedata;
21982 if (ba_cache.symtab == NULL)
21983 return NULL;
21985 /* Find a symbol whose value matches offset. */
21986 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
21987 if (sym->st_value == offset)
21989 if (sym->st_name >= ba_cache.strtablen)
21990 /* Huh ? This should not happen. */
21991 continue;
21993 if (ba_cache.strtab[sym->st_name] == 0)
21994 continue;
21996 /* The AArch64, ARM and RISC-V architectures define mapping symbols
21997 (eg $d, $x, $t) which we want to ignore. */
21998 if (ba_cache.strtab[sym->st_name] == '$'
21999 && ba_cache.strtab[sym->st_name + 1] != 0
22000 && ba_cache.strtab[sym->st_name + 2] == 0)
22001 continue;
22003 if (is_open_attr)
22005 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
22006 and FILE or OBJECT symbols over NOTYPE symbols. We skip
22007 FUNC symbols entirely. */
22008 switch (ELF_ST_TYPE (sym->st_info))
22010 case STT_OBJECT:
22011 case STT_FILE:
22012 saved_sym = sym;
22013 if (sym->st_size)
22015 /* If the symbol has a size associated
22016 with it then we can stop searching. */
22017 sym = ba_cache.symtab + ba_cache.nsyms;
22019 continue;
22021 case STT_FUNC:
22022 /* Ignore function symbols. */
22023 continue;
22025 default:
22026 break;
22029 switch (ELF_ST_BIND (sym->st_info))
22031 case STB_GLOBAL:
22032 if (saved_sym == NULL
22033 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
22034 saved_sym = sym;
22035 break;
22037 case STB_LOCAL:
22038 if (saved_sym == NULL)
22039 saved_sym = sym;
22040 break;
22042 default:
22043 break;
22046 else
22048 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
22049 continue;
22051 saved_sym = sym;
22052 break;
22056 if (saved_sym && pname)
22057 * pname = ba_cache.strtab + saved_sym->st_name;
22059 return saved_sym;
22062 /* Returns true iff addr1 and addr2 are in the same section. */
22064 static bool
22065 same_section (Filedata * filedata, uint64_t addr1, uint64_t addr2)
22067 Elf_Internal_Shdr * a1;
22068 Elf_Internal_Shdr * a2;
22070 a1 = find_section_by_address (filedata, addr1);
22071 a2 = find_section_by_address (filedata, addr2);
22073 return a1 == a2 && a1 != NULL;
22076 static bool
22077 print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
22078 Filedata * filedata)
22080 static uint64_t global_offset = 0;
22081 static uint64_t global_end = 0;
22082 static uint64_t func_offset = 0;
22083 static uint64_t func_end = 0;
22085 Elf_Internal_Sym *sym;
22086 const char *name;
22087 uint64_t start;
22088 uint64_t end;
22089 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
22091 switch (pnote->descsz)
22093 case 0:
22094 /* A zero-length description means that the range of
22095 the previous note of the same type should be used. */
22096 if (is_open_attr)
22098 if (global_end > global_offset)
22099 printf (_(" Applies to region from %#" PRIx64
22100 " to %#" PRIx64 "\n"), global_offset, global_end);
22101 else
22102 printf (_(" Applies to region from %#" PRIx64
22103 "\n"), global_offset);
22105 else
22107 if (func_end > func_offset)
22108 printf (_(" Applies to region from %#" PRIx64
22109 " to %#" PRIx64 "\n"), func_offset, func_end);
22110 else
22111 printf (_(" Applies to region from %#" PRIx64
22112 "\n"), func_offset);
22114 return true;
22116 case 4:
22117 start = byte_get ((unsigned char *) pnote->descdata, 4);
22118 end = 0;
22119 break;
22121 case 8:
22122 start = byte_get ((unsigned char *) pnote->descdata, 4);
22123 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
22124 break;
22126 case 16:
22127 start = byte_get ((unsigned char *) pnote->descdata, 8);
22128 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
22129 break;
22131 default:
22132 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
22133 printf (_(" <invalid descsz>"));
22134 return false;
22137 name = NULL;
22138 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
22139 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
22140 in order to avoid them being confused with the start address of the
22141 first function in the file... */
22142 if (sym == NULL && is_open_attr)
22143 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
22144 & name);
22146 if (end == 0 && sym != NULL && sym->st_size > 0)
22147 end = start + sym->st_size;
22149 if (is_open_attr)
22151 /* FIXME: Need to properly allow for section alignment.
22152 16 is just the alignment used on x86_64. */
22153 if (global_end > 0
22154 && start > BFD_ALIGN (global_end, 16)
22155 /* Build notes are not guaranteed to be organised in order of
22156 increasing address, but we should find the all of the notes
22157 for one section in the same place. */
22158 && same_section (filedata, start, global_end))
22159 warn (_("Gap in build notes detected from %#" PRIx64
22160 " to %#" PRIx64 "\n"),
22161 global_end + 1, start - 1);
22163 printf (_(" Applies to region from %#" PRIx64), start);
22164 global_offset = start;
22166 if (end)
22168 printf (_(" to %#" PRIx64), end);
22169 global_end = end;
22172 else
22174 printf (_(" Applies to region from %#" PRIx64), start);
22175 func_offset = start;
22177 if (end)
22179 printf (_(" to %#" PRIx64), end);
22180 func_end = end;
22184 if (sym && name)
22185 printf (_(" (%s)"), name);
22187 printf ("\n");
22188 return true;
22191 static bool
22192 print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
22194 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
22195 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
22196 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
22197 char name_type;
22198 char name_attribute;
22199 const char * expected_types;
22200 const char * name = pnote->namedata;
22201 const char * text;
22202 signed int left;
22204 if (name == NULL || pnote->namesz < 2)
22206 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
22207 print_symbol_name (-20, _(" <corrupt name>"));
22208 return false;
22211 if (do_wide)
22212 left = 28;
22213 else
22214 left = 20;
22216 /* Version 2 of the spec adds a "GA" prefix to the name field. */
22217 if (name[0] == 'G' && name[1] == 'A')
22219 if (pnote->namesz < 4)
22221 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
22222 print_symbol_name (-20, _(" <corrupt name>"));
22223 return false;
22226 printf ("GA");
22227 name += 2;
22228 left -= 2;
22231 switch ((name_type = * name))
22233 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
22234 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
22235 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
22236 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
22237 printf ("%c", * name);
22238 left --;
22239 break;
22240 default:
22241 error (_("unrecognised attribute type in name field: %d\n"), name_type);
22242 print_symbol_name (-20, _("<unknown name type>"));
22243 return false;
22246 ++ name;
22247 text = NULL;
22249 switch ((name_attribute = * name))
22251 case GNU_BUILD_ATTRIBUTE_VERSION:
22252 text = _("<version>");
22253 expected_types = string_expected;
22254 ++ name;
22255 break;
22256 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
22257 text = _("<stack prot>");
22258 expected_types = "!+*";
22259 ++ name;
22260 break;
22261 case GNU_BUILD_ATTRIBUTE_RELRO:
22262 text = _("<relro>");
22263 expected_types = bool_expected;
22264 ++ name;
22265 break;
22266 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
22267 text = _("<stack size>");
22268 expected_types = number_expected;
22269 ++ name;
22270 break;
22271 case GNU_BUILD_ATTRIBUTE_TOOL:
22272 text = _("<tool>");
22273 expected_types = string_expected;
22274 ++ name;
22275 break;
22276 case GNU_BUILD_ATTRIBUTE_ABI:
22277 text = _("<ABI>");
22278 expected_types = "$*";
22279 ++ name;
22280 break;
22281 case GNU_BUILD_ATTRIBUTE_PIC:
22282 text = _("<PIC>");
22283 expected_types = number_expected;
22284 ++ name;
22285 break;
22286 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
22287 text = _("<short enum>");
22288 expected_types = bool_expected;
22289 ++ name;
22290 break;
22291 default:
22292 if (ISPRINT (* name))
22294 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
22296 if (len > left && ! do_wide)
22297 len = left;
22298 printf ("%.*s:", len, name);
22299 left -= len;
22300 name += len;
22302 else
22304 static char tmpbuf [128];
22306 error (_("unrecognised byte in name field: %d\n"), * name);
22307 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
22308 text = tmpbuf;
22309 name ++;
22311 expected_types = "*$!+";
22312 break;
22315 if (text)
22316 left -= printf ("%s", text);
22318 if (strchr (expected_types, name_type) == NULL)
22319 warn (_("attribute does not have an expected type (%c)\n"), name_type);
22321 if ((size_t) (name - pnote->namedata) > pnote->namesz)
22323 error (_("corrupt name field: namesz: %lu but parsing gets to %td\n"),
22324 pnote->namesz,
22325 name - pnote->namedata);
22326 return false;
22329 if (left < 1 && ! do_wide)
22330 return true;
22332 switch (name_type)
22334 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
22336 unsigned int bytes;
22337 uint64_t val = 0;
22338 unsigned int shift = 0;
22339 char *decoded = NULL;
22341 bytes = pnote->namesz - (name - pnote->namedata);
22342 if (bytes > 0)
22343 /* The -1 is because the name field is always 0 terminated, and we
22344 want to be able to ensure that the shift in the while loop below
22345 will not overflow. */
22346 -- bytes;
22348 if (bytes > sizeof (val))
22350 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
22351 bytes);
22352 bytes = sizeof (val);
22354 /* We do not bother to warn if bytes == 0 as this can
22355 happen with some early versions of the gcc plugin. */
22357 while (bytes --)
22359 uint64_t byte = *name++ & 0xff;
22361 val |= byte << shift;
22362 shift += 8;
22365 switch (name_attribute)
22367 case GNU_BUILD_ATTRIBUTE_PIC:
22368 switch (val)
22370 case 0: decoded = "static"; break;
22371 case 1: decoded = "pic"; break;
22372 case 2: decoded = "PIC"; break;
22373 case 3: decoded = "pie"; break;
22374 case 4: decoded = "PIE"; break;
22375 default: break;
22377 break;
22378 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
22379 switch (val)
22381 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
22382 case 0: decoded = "off"; break;
22383 case 1: decoded = "on"; break;
22384 case 2: decoded = "all"; break;
22385 case 3: decoded = "strong"; break;
22386 case 4: decoded = "explicit"; break;
22387 default: break;
22389 break;
22390 default:
22391 break;
22394 if (decoded != NULL)
22396 print_symbol_name (-left, decoded);
22397 left = 0;
22399 else if (val == 0)
22401 printf ("0x0");
22402 left -= 3;
22404 else
22406 if (do_wide)
22407 left -= printf ("0x%" PRIx64, val);
22408 else
22409 left -= printf ("0x%-.*" PRIx64, left, val);
22412 break;
22413 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
22414 left -= print_symbol_name (- left, name);
22415 break;
22416 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
22417 left -= print_symbol_name (- left, "true");
22418 break;
22419 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
22420 left -= print_symbol_name (- left, "false");
22421 break;
22424 if (do_wide && left > 0)
22425 printf ("%-*s", left, " ");
22427 return true;
22430 /* Print the contents of PNOTE as hex. */
22432 static void
22433 print_note_contents_hex (Elf_Internal_Note *pnote)
22435 if (pnote->descsz)
22437 size_t i;
22439 printf (_(" description data: "));
22440 for (i = 0; i < pnote->descsz; i++)
22441 printf ("%02x ", pnote->descdata[i] & 0xff);
22442 if (!do_wide)
22443 printf ("\n");
22446 if (do_wide)
22447 printf ("\n");
22450 #if defined HAVE_MSGPACK
22452 static void
22453 print_indents (int n)
22455 printf (" ");
22457 for (int i = 0; i < n; i++)
22458 printf (" ");
22461 /* Print OBJ in human-readable form. */
22463 static void
22464 dump_msgpack_obj (const msgpack_object *obj, int indent)
22466 switch (obj->type)
22468 case MSGPACK_OBJECT_NIL:
22469 printf ("(nil)");
22470 break;
22472 case MSGPACK_OBJECT_BOOLEAN:
22473 printf ("%s", obj->via.boolean ? "true" : "false");
22474 break;
22476 case MSGPACK_OBJECT_POSITIVE_INTEGER:
22477 printf ("%" PRIu64, obj->via.u64);
22478 break;
22480 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
22481 printf ("%" PRIi64, obj->via.i64);
22482 break;
22484 case MSGPACK_OBJECT_FLOAT32:
22485 case MSGPACK_OBJECT_FLOAT64:
22486 printf ("%f", obj->via.f64);
22487 break;
22489 case MSGPACK_OBJECT_STR:
22490 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
22491 break;
22493 case MSGPACK_OBJECT_ARRAY:
22495 const msgpack_object_array *array = &obj->via.array;
22497 printf ("[\n");
22498 ++indent;
22500 for (uint32_t i = 0; i < array->size; ++i)
22502 const msgpack_object *item = &array->ptr[i];
22504 print_indents (indent);
22505 dump_msgpack_obj (item, indent);
22506 printf (",\n");
22509 --indent;
22510 print_indents (indent);
22511 printf ("]");
22512 break;
22514 break;
22516 case MSGPACK_OBJECT_MAP:
22518 const msgpack_object_map *map = &obj->via.map;
22520 printf ("{\n");
22521 ++indent;
22523 for (uint32_t i = 0; i < map->size; ++i)
22525 const msgpack_object_kv *kv = &map->ptr[i];
22526 const msgpack_object *key = &kv->key;
22527 const msgpack_object *val = &kv->val;
22529 print_indents (indent);
22530 dump_msgpack_obj (key, indent);
22531 printf (": ");
22532 dump_msgpack_obj (val, indent);
22534 printf (",\n");
22537 --indent;
22538 print_indents (indent);
22539 printf ("}");
22541 break;
22544 case MSGPACK_OBJECT_BIN:
22545 printf ("(bin)");
22546 break;
22548 case MSGPACK_OBJECT_EXT:
22549 printf ("(ext)");
22550 break;
22554 static void
22555 dump_msgpack (const msgpack_unpacked *msg)
22557 print_indents (0);
22558 dump_msgpack_obj (&msg->data, 0);
22559 printf ("\n");
22562 #endif /* defined HAVE_MSGPACK */
22564 static bool
22565 print_amdgpu_note (Elf_Internal_Note *pnote)
22567 #if defined HAVE_MSGPACK
22568 /* If msgpack is available, decode and dump the note's content. */
22569 bool ret;
22570 msgpack_unpacked msg;
22571 msgpack_unpack_return msgpack_ret;
22573 assert (pnote->type == NT_AMDGPU_METADATA);
22575 msgpack_unpacked_init (&msg);
22576 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
22577 NULL);
22579 switch (msgpack_ret)
22581 case MSGPACK_UNPACK_SUCCESS:
22582 dump_msgpack (&msg);
22583 ret = true;
22584 break;
22586 default:
22587 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
22588 ret = false;
22589 break;
22592 msgpack_unpacked_destroy (&msg);
22593 return ret;
22594 #else
22595 /* msgpack is not available, dump contents as hex. */
22596 print_note_contents_hex (pnote);
22597 return true;
22598 #endif
22601 static bool
22602 print_qnx_note (Elf_Internal_Note *pnote)
22604 switch (pnote->type)
22606 case QNT_STACK:
22607 if (pnote->descsz != 12)
22608 goto desc_size_fail;
22610 printf (_(" Stack Size: 0x%" PRIx32 "\n"),
22611 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4));
22612 printf (_(" Stack allocated: %" PRIx32 "\n"),
22613 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
22614 printf (_(" Executable: %s\n"),
22615 ((unsigned) byte_get ((unsigned char *) pnote->descdata + 8, 1)) ? "no": "yes");
22616 break;
22618 default:
22619 print_note_contents_hex(pnote);
22621 return true;
22623 desc_size_fail:
22624 printf (_(" <corrupt - data size is too small>\n"));
22625 error (_("corrupt QNX note: data size is too small\n"));
22626 return false;
22630 /* Note that by the ELF standard, the name field is already null byte
22631 terminated, and namesz includes the terminating null byte.
22632 I.E. the value of namesz for the name "FSF" is 4.
22634 If the value of namesz is zero, there is no name present. */
22636 static bool
22637 process_note (Elf_Internal_Note * pnote,
22638 Filedata * filedata)
22640 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
22641 const char * nt;
22643 if (pnote->namesz == 0)
22644 /* If there is no note name, then use the default set of
22645 note type strings. */
22646 nt = get_note_type (filedata, pnote->type);
22648 else if (startswith (pnote->namedata, "GNU"))
22649 /* GNU-specific object file notes. */
22650 nt = get_gnu_elf_note_type (pnote->type);
22652 else if (startswith (pnote->namedata, "AMDGPU"))
22653 /* AMDGPU-specific object file notes. */
22654 nt = get_amdgpu_elf_note_type (pnote->type);
22656 else if (startswith (pnote->namedata, "FreeBSD"))
22657 /* FreeBSD-specific core file notes. */
22658 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
22660 else if (startswith (pnote->namedata, "NetBSD-CORE"))
22661 /* NetBSD-specific core file notes. */
22662 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
22664 else if (startswith (pnote->namedata, "NetBSD"))
22665 /* NetBSD-specific core file notes. */
22666 return process_netbsd_elf_note (pnote);
22668 else if (startswith (pnote->namedata, "PaX"))
22669 /* NetBSD-specific core file notes. */
22670 return process_netbsd_elf_note (pnote);
22672 else if (startswith (pnote->namedata, "OpenBSD"))
22673 /* OpenBSD-specific core file notes. */
22674 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
22676 else if (startswith (pnote->namedata, "QNX"))
22677 /* QNX-specific core file notes. */
22678 nt = get_qnx_elfcore_note_type (filedata, pnote->type);
22680 else if (startswith (pnote->namedata, "SPU/"))
22682 /* SPU-specific core file notes. */
22683 nt = pnote->namedata + 4;
22684 name = "SPU";
22687 else if (startswith (pnote->namedata, "IPF/VMS"))
22688 /* VMS/ia64-specific file notes. */
22689 nt = get_ia64_vms_note_type (pnote->type);
22691 else if (startswith (pnote->namedata, "stapsdt"))
22692 nt = get_stapsdt_note_type (pnote->type);
22694 else
22695 /* Don't recognize this note name; just use the default set of
22696 note type strings. */
22697 nt = get_note_type (filedata, pnote->type);
22699 printf (" ");
22701 if (((startswith (pnote->namedata, "GA")
22702 && strchr ("*$!+", pnote->namedata[2]) != NULL)
22703 || strchr ("*$!+", pnote->namedata[0]) != NULL)
22704 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
22705 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
22706 print_gnu_build_attribute_name (pnote);
22707 else
22708 print_symbol_name (-20, name);
22710 if (do_wide)
22711 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
22712 else
22713 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
22715 if (startswith (pnote->namedata, "IPF/VMS"))
22716 return print_ia64_vms_note (pnote);
22717 else if (startswith (pnote->namedata, "GNU"))
22718 return print_gnu_note (filedata, pnote);
22719 else if (startswith (pnote->namedata, "stapsdt"))
22720 return print_stapsdt_note (pnote);
22721 else if (startswith (pnote->namedata, "CORE"))
22722 return print_core_note (pnote);
22723 else if (startswith (pnote->namedata, "FDO"))
22724 return print_fdo_note (pnote);
22725 else if (((startswith (pnote->namedata, "GA")
22726 && strchr ("*$!+", pnote->namedata[2]) != NULL)
22727 || strchr ("*$!+", pnote->namedata[0]) != NULL)
22728 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
22729 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
22730 return print_gnu_build_attribute_description (pnote, filedata);
22731 else if (startswith (pnote->namedata, "AMDGPU")
22732 && pnote->type == NT_AMDGPU_METADATA)
22733 return print_amdgpu_note (pnote);
22734 else if (startswith (pnote->namedata, "QNX"))
22735 return print_qnx_note (pnote);
22737 print_note_contents_hex (pnote);
22738 return true;
22741 static bool
22742 process_notes_at (Filedata * filedata,
22743 Elf_Internal_Shdr * section,
22744 uint64_t offset,
22745 uint64_t length,
22746 uint64_t align)
22748 Elf_External_Note *pnotes;
22749 Elf_External_Note *external;
22750 char *end;
22751 bool res = true;
22753 if (length <= 0)
22754 return false;
22756 if (section)
22758 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
22759 if (pnotes)
22761 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
22763 free (pnotes);
22764 return false;
22768 else
22769 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
22770 _("notes"));
22772 if (pnotes == NULL)
22773 return false;
22775 external = pnotes;
22777 if (filedata->is_separate)
22778 printf (_("In linked file '%s': "), filedata->file_name);
22779 else
22780 printf ("\n");
22781 if (section)
22782 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
22783 else
22784 printf (_("Displaying notes found at file offset 0x%08" PRIx64
22785 " with length 0x%08" PRIx64 ":\n"),
22786 offset, length);
22788 /* NB: Some note sections may have alignment value of 0 or 1. gABI
22789 specifies that notes should be aligned to 4 bytes in 32-bit
22790 objects and to 8 bytes in 64-bit objects. As a Linux extension,
22791 we also support 4 byte alignment in 64-bit objects. If section
22792 alignment is less than 4, we treate alignment as 4 bytes. */
22793 if (align < 4)
22794 align = 4;
22795 else if (align != 4 && align != 8)
22797 warn (_("Corrupt note: alignment %" PRId64 ", expecting 4 or 8\n"),
22798 align);
22799 free (pnotes);
22800 return false;
22803 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
22805 end = (char *) pnotes + length;
22806 while ((char *) external < end)
22808 Elf_Internal_Note inote;
22809 size_t min_notesz;
22810 char * next;
22811 char * temp = NULL;
22812 size_t data_remaining = end - (char *) external;
22814 if (!is_ia64_vms (filedata))
22816 /* PR binutils/15191
22817 Make sure that there is enough data to read. */
22818 min_notesz = offsetof (Elf_External_Note, name);
22819 if (data_remaining < min_notesz)
22821 warn (ngettext ("Corrupt note: only %zd byte remains, "
22822 "not enough for a full note\n",
22823 "Corrupt note: only %zd bytes remain, "
22824 "not enough for a full note\n",
22825 data_remaining),
22826 data_remaining);
22827 break;
22829 data_remaining -= min_notesz;
22831 inote.type = BYTE_GET (external->type);
22832 inote.namesz = BYTE_GET (external->namesz);
22833 inote.namedata = external->name;
22834 inote.descsz = BYTE_GET (external->descsz);
22835 inote.descdata = ((char *) external
22836 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
22837 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22838 next = ((char *) external
22839 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
22841 else
22843 Elf64_External_VMS_Note *vms_external;
22845 /* PR binutils/15191
22846 Make sure that there is enough data to read. */
22847 min_notesz = offsetof (Elf64_External_VMS_Note, name);
22848 if (data_remaining < min_notesz)
22850 warn (ngettext ("Corrupt note: only %zd byte remains, "
22851 "not enough for a full note\n",
22852 "Corrupt note: only %zd bytes remain, "
22853 "not enough for a full note\n",
22854 data_remaining),
22855 data_remaining);
22856 break;
22858 data_remaining -= min_notesz;
22860 vms_external = (Elf64_External_VMS_Note *) external;
22861 inote.type = BYTE_GET (vms_external->type);
22862 inote.namesz = BYTE_GET (vms_external->namesz);
22863 inote.namedata = vms_external->name;
22864 inote.descsz = BYTE_GET (vms_external->descsz);
22865 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
22866 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22867 next = inote.descdata + align_power (inote.descsz, 3);
22870 /* PR 17531: file: 3443835e. */
22871 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
22872 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
22873 || (size_t) (inote.descdata - inote.namedata) > data_remaining
22874 || (size_t) (next - inote.descdata) < inote.descsz
22875 || ((size_t) (next - inote.descdata)
22876 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
22878 warn (_("note with invalid namesz and/or descsz found at offset %#tx\n"),
22879 (char *) external - (char *) pnotes);
22880 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx, alignment: %u\n"),
22881 inote.type, inote.namesz, inote.descsz, (int) align);
22882 break;
22885 external = (Elf_External_Note *) next;
22887 /* Verify that name is null terminated. It appears that at least
22888 one version of Linux (RedHat 6.0) generates corefiles that don't
22889 comply with the ELF spec by failing to include the null byte in
22890 namesz. */
22891 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
22893 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
22895 temp = (char *) malloc (inote.namesz + 1);
22896 if (temp == NULL)
22898 error (_("Out of memory allocating space for inote name\n"));
22899 res = false;
22900 break;
22903 memcpy (temp, inote.namedata, inote.namesz);
22904 inote.namedata = temp;
22906 inote.namedata[inote.namesz] = 0;
22909 if (! process_note (& inote, filedata))
22910 res = false;
22912 free (temp);
22913 temp = NULL;
22916 free (pnotes);
22918 return res;
22921 static bool
22922 process_corefile_note_segments (Filedata * filedata)
22924 Elf_Internal_Phdr *segment;
22925 unsigned int i;
22926 bool res = true;
22928 if (! get_program_headers (filedata))
22929 return true;
22931 for (i = 0, segment = filedata->program_headers;
22932 i < filedata->file_header.e_phnum;
22933 i++, segment++)
22935 if (segment->p_type == PT_NOTE)
22936 if (! process_notes_at (filedata, NULL, segment->p_offset,
22937 segment->p_filesz, segment->p_align))
22938 res = false;
22941 return res;
22944 static bool
22945 process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
22947 Elf_External_Note * pnotes;
22948 Elf_External_Note * external;
22949 char * end;
22950 bool res = true;
22952 if (length <= 0)
22953 return false;
22955 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
22956 _("v850 notes"));
22957 if (pnotes == NULL)
22958 return false;
22960 external = pnotes;
22961 end = (char*) pnotes + length;
22963 printf (_("\nDisplaying contents of Renesas V850 notes section at offset"
22964 " %#" PRIx64 " with length %#" PRIx64 ":\n"),
22965 offset, length);
22967 while ((char *) external + sizeof (Elf_External_Note) < end)
22969 Elf_External_Note * next;
22970 Elf_Internal_Note inote;
22972 inote.type = BYTE_GET (external->type);
22973 inote.namesz = BYTE_GET (external->namesz);
22974 inote.namedata = external->name;
22975 inote.descsz = BYTE_GET (external->descsz);
22976 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
22977 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22979 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
22981 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
22982 inote.descdata = inote.namedata;
22983 inote.namesz = 0;
22986 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
22988 if ( ((char *) next > end)
22989 || ((char *) next < (char *) pnotes))
22991 warn (_("corrupt descsz found in note at offset %#tx\n"),
22992 (char *) external - (char *) pnotes);
22993 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
22994 inote.type, inote.namesz, inote.descsz);
22995 break;
22998 external = next;
23000 /* Prevent out-of-bounds indexing. */
23001 if ( inote.namedata + inote.namesz > end
23002 || inote.namedata + inote.namesz < inote.namedata)
23004 warn (_("corrupt namesz found in note at offset %#zx\n"),
23005 (char *) external - (char *) pnotes);
23006 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
23007 inote.type, inote.namesz, inote.descsz);
23008 break;
23011 printf (" %s: ", get_v850_elf_note_type (inote.type));
23013 if (! print_v850_note (& inote))
23015 res = false;
23016 printf ("<corrupt sizes: namesz: %#lx, descsz: %#lx>\n",
23017 inote.namesz, inote.descsz);
23021 free (pnotes);
23023 return res;
23026 static bool
23027 process_note_sections (Filedata * filedata)
23029 Elf_Internal_Shdr *section;
23030 size_t i;
23031 unsigned int n = 0;
23032 bool res = true;
23034 for (i = 0, section = filedata->section_headers;
23035 i < filedata->file_header.e_shnum && section != NULL;
23036 i++, section++)
23038 if (section->sh_type == SHT_NOTE)
23040 if (! process_notes_at (filedata, section, section->sh_offset,
23041 section->sh_size, section->sh_addralign))
23042 res = false;
23043 n++;
23046 if (( filedata->file_header.e_machine == EM_V800
23047 || filedata->file_header.e_machine == EM_V850
23048 || filedata->file_header.e_machine == EM_CYGNUS_V850)
23049 && section->sh_type == SHT_RENESAS_INFO)
23051 if (! process_v850_notes (filedata, section->sh_offset,
23052 section->sh_size))
23053 res = false;
23054 n++;
23058 if (n == 0)
23059 /* Try processing NOTE segments instead. */
23060 return process_corefile_note_segments (filedata);
23062 return res;
23065 static bool
23066 process_notes (Filedata * filedata)
23068 /* If we have not been asked to display the notes then do nothing. */
23069 if (! do_notes)
23070 return true;
23072 if (filedata->file_header.e_type != ET_CORE)
23073 return process_note_sections (filedata);
23075 /* No program headers means no NOTE segment. */
23076 if (filedata->file_header.e_phnum > 0)
23077 return process_corefile_note_segments (filedata);
23079 if (filedata->is_separate)
23080 printf (_("No notes found in linked file '%s'.\n"),
23081 filedata->file_name);
23082 else
23083 printf (_("No notes found file.\n"));
23085 return true;
23088 static unsigned char *
23089 display_public_gnu_attributes (unsigned char * start,
23090 const unsigned char * const end)
23092 printf (_(" Unknown GNU attribute: %s\n"), start);
23094 start += strnlen ((char *) start, end - start);
23095 display_raw_attribute (start, end);
23097 return (unsigned char *) end;
23100 static unsigned char *
23101 display_generic_attribute (unsigned char * start,
23102 unsigned int tag,
23103 const unsigned char * const end)
23105 if (tag == 0)
23106 return (unsigned char *) end;
23108 return display_tag_value (tag, start, end);
23111 static bool
23112 process_arch_specific (Filedata * filedata)
23114 if (! do_arch)
23115 return true;
23117 switch (filedata->file_header.e_machine)
23119 case EM_ARC:
23120 case EM_ARC_COMPACT:
23121 case EM_ARC_COMPACT2:
23122 case EM_ARC_COMPACT3:
23123 case EM_ARC_COMPACT3_64:
23124 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
23125 display_arc_attribute,
23126 display_generic_attribute);
23127 case EM_ARM:
23128 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
23129 display_arm_attribute,
23130 display_generic_attribute);
23132 case EM_MIPS:
23133 case EM_MIPS_RS3_LE:
23134 return process_mips_specific (filedata);
23136 case EM_MSP430:
23137 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
23138 display_msp430_attribute,
23139 display_msp430_gnu_attribute);
23141 case EM_RISCV:
23142 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
23143 display_riscv_attribute,
23144 display_generic_attribute);
23146 case EM_NDS32:
23147 return process_nds32_specific (filedata);
23149 case EM_68K:
23150 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
23151 display_m68k_gnu_attribute);
23153 case EM_PPC:
23154 case EM_PPC64:
23155 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
23156 display_power_gnu_attribute);
23158 case EM_S390:
23159 case EM_S390_OLD:
23160 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
23161 display_s390_gnu_attribute);
23163 case EM_SPARC:
23164 case EM_SPARC32PLUS:
23165 case EM_SPARCV9:
23166 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
23167 display_sparc_gnu_attribute);
23169 case EM_TI_C6000:
23170 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
23171 display_tic6x_attribute,
23172 display_generic_attribute);
23174 case EM_CSKY:
23175 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
23176 display_csky_attribute, NULL);
23178 default:
23179 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
23180 display_public_gnu_attributes,
23181 display_generic_attribute);
23185 static bool
23186 get_file_header (Filedata * filedata)
23188 /* Read in the identity array. */
23189 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
23190 return false;
23192 /* Determine how to read the rest of the header. */
23193 switch (filedata->file_header.e_ident[EI_DATA])
23195 default:
23196 case ELFDATANONE:
23197 case ELFDATA2LSB:
23198 byte_get = byte_get_little_endian;
23199 byte_put = byte_put_little_endian;
23200 break;
23201 case ELFDATA2MSB:
23202 byte_get = byte_get_big_endian;
23203 byte_put = byte_put_big_endian;
23204 break;
23207 /* For now we only support 32 bit and 64 bit ELF files. */
23208 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
23210 /* Read in the rest of the header. */
23211 if (is_32bit_elf)
23213 Elf32_External_Ehdr ehdr32;
23215 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
23216 return false;
23218 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
23219 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
23220 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
23221 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
23222 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
23223 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
23224 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
23225 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
23226 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
23227 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
23228 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
23229 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
23230 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
23232 else
23234 Elf64_External_Ehdr ehdr64;
23236 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
23237 return false;
23239 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
23240 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
23241 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
23242 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
23243 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
23244 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
23245 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
23246 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
23247 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
23248 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
23249 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
23250 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
23251 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
23254 return true;
23257 static void
23258 free_filedata (Filedata *filedata)
23260 free (filedata->program_interpreter);
23261 free (filedata->program_headers);
23262 free (filedata->section_headers);
23263 free (filedata->string_table);
23264 free (filedata->dump.dump_sects);
23265 free (filedata->dynamic_strings);
23266 free (filedata->dynamic_symbols);
23267 free (filedata->dynamic_syminfo);
23268 free (filedata->dynamic_section);
23270 while (filedata->symtab_shndx_list != NULL)
23272 elf_section_list *next = filedata->symtab_shndx_list->next;
23273 free (filedata->symtab_shndx_list);
23274 filedata->symtab_shndx_list = next;
23277 free (filedata->section_headers_groups);
23279 if (filedata->section_groups)
23281 size_t i;
23282 struct group_list * g;
23283 struct group_list * next;
23285 for (i = 0; i < filedata->group_count; i++)
23287 for (g = filedata->section_groups [i].root; g != NULL; g = next)
23289 next = g->next;
23290 free (g);
23294 free (filedata->section_groups);
23296 memset (&filedata->section_headers, 0,
23297 sizeof (Filedata) - offsetof (Filedata, section_headers));
23300 static void
23301 close_file (Filedata * filedata)
23303 if (filedata)
23305 if (filedata->handle)
23306 fclose (filedata->handle);
23307 free (filedata);
23311 void
23312 close_debug_file (void * data)
23314 free_filedata ((Filedata *) data);
23315 close_file ((Filedata *) data);
23318 static Filedata *
23319 open_file (const char * pathname, bool is_separate)
23321 struct stat statbuf;
23322 Filedata * filedata = NULL;
23324 if (stat (pathname, & statbuf) < 0
23325 || ! S_ISREG (statbuf.st_mode))
23326 goto fail;
23328 filedata = calloc (1, sizeof * filedata);
23329 if (filedata == NULL)
23330 goto fail;
23332 filedata->handle = fopen (pathname, "rb");
23333 if (filedata->handle == NULL)
23334 goto fail;
23336 filedata->file_size = statbuf.st_size;
23337 filedata->file_name = pathname;
23338 filedata->is_separate = is_separate;
23340 if (! get_file_header (filedata))
23341 goto fail;
23343 if (!get_section_headers (filedata, false))
23344 goto fail;
23346 return filedata;
23348 fail:
23349 if (filedata)
23351 if (filedata->handle)
23352 fclose (filedata->handle);
23353 free (filedata);
23355 return NULL;
23358 void *
23359 open_debug_file (const char * pathname)
23361 return open_file (pathname, true);
23364 static void
23365 initialise_dump_sects (Filedata * filedata)
23367 /* Initialise the dump_sects array from the cmdline_dump_sects array.
23368 Note we do this even if cmdline_dump_sects is empty because we
23369 must make sure that the dump_sets array is zeroed out before each
23370 object file is processed. */
23371 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
23372 memset (filedata->dump.dump_sects, 0,
23373 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
23375 if (cmdline.num_dump_sects > 0)
23377 if (filedata->dump.num_dump_sects == 0)
23378 /* A sneaky way of allocating the dump_sects array. */
23379 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
23381 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
23382 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
23383 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
23387 static bool
23388 might_need_separate_debug_info (Filedata * filedata)
23390 /* Debuginfo files do not need further separate file loading. */
23391 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
23392 return false;
23394 /* Since do_follow_links might be enabled by default, only treat it as an
23395 indication that separate files should be loaded if setting it was a
23396 deliberate user action. */
23397 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
23398 return true;
23400 if (process_links || do_syms || do_unwind
23401 || dump_any_debugging || do_dump || do_debugging)
23402 return true;
23404 return false;
23407 /* Process one ELF object file according to the command line options.
23408 This file may actually be stored in an archive. The file is
23409 positioned at the start of the ELF object. Returns TRUE if no
23410 problems were encountered, FALSE otherwise. */
23412 static bool
23413 process_object (Filedata * filedata)
23415 bool have_separate_files;
23416 unsigned int i;
23417 bool res;
23419 if (! get_file_header (filedata))
23421 error (_("%s: Failed to read file header\n"), filedata->file_name);
23422 return false;
23425 /* Initialise per file variables. */
23426 for (i = ARRAY_SIZE (filedata->version_info); i--;)
23427 filedata->version_info[i] = 0;
23429 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
23430 filedata->dynamic_info[i] = 0;
23431 filedata->dynamic_info_DT_GNU_HASH = 0;
23432 filedata->dynamic_info_DT_MIPS_XHASH = 0;
23434 /* Process the file. */
23435 if (show_name)
23436 printf (_("\nFile: %s\n"), filedata->file_name);
23438 initialise_dump_sects (filedata);
23440 /* There may be some extensions in the first section header. Don't
23441 bomb if we can't read it. */
23442 get_section_headers (filedata, true);
23444 if (! process_file_header (filedata))
23446 res = false;
23447 goto out;
23450 /* Throw away the single section header read above, so that we
23451 re-read the entire set. */
23452 free (filedata->section_headers);
23453 filedata->section_headers = NULL;
23455 if (! process_section_headers (filedata))
23457 /* Without loaded section headers we cannot process lots of things. */
23458 do_unwind = do_version = do_dump = do_arch = false;
23460 if (! do_using_dynamic)
23461 do_syms = do_dyn_syms = do_reloc = false;
23464 if (! process_section_groups (filedata))
23465 /* Without loaded section groups we cannot process unwind. */
23466 do_unwind = false;
23468 process_program_headers (filedata);
23470 res = process_dynamic_section (filedata);
23472 if (! process_relocs (filedata))
23473 res = false;
23475 if (! process_unwind (filedata))
23476 res = false;
23478 if (! process_symbol_table (filedata))
23479 res = false;
23481 if (! process_lto_symbol_tables (filedata))
23482 res = false;
23484 if (! process_syminfo (filedata))
23485 res = false;
23487 if (! process_version_sections (filedata))
23488 res = false;
23490 if (might_need_separate_debug_info (filedata))
23491 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
23492 else
23493 have_separate_files = false;
23495 if (! process_section_contents (filedata))
23496 res = false;
23498 if (have_separate_files)
23500 separate_info * d;
23502 for (d = first_separate_info; d != NULL; d = d->next)
23504 initialise_dump_sects (d->handle);
23506 if (process_links && ! process_file_header (d->handle))
23507 res = false;
23508 else if (! process_section_headers (d->handle))
23509 res = false;
23510 else if (! process_section_contents (d->handle))
23511 res = false;
23512 else if (process_links)
23514 if (! process_section_groups (d->handle))
23515 res = false;
23516 process_program_headers (d->handle);
23517 if (! process_dynamic_section (d->handle))
23518 res = false;
23519 if (! process_relocs (d->handle))
23520 res = false;
23521 if (! process_unwind (d->handle))
23522 res = false;
23523 if (! process_symbol_table (d->handle))
23524 res = false;
23525 if (! process_lto_symbol_tables (d->handle))
23526 res = false;
23527 if (! process_syminfo (d->handle))
23528 res = false;
23529 if (! process_version_sections (d->handle))
23530 res = false;
23531 if (! process_notes (d->handle))
23532 res = false;
23536 /* The file handles are closed by the call to free_debug_memory() below. */
23539 if (! process_notes (filedata))
23540 res = false;
23542 if (! process_gnu_liblist (filedata))
23543 res = false;
23545 if (! process_arch_specific (filedata))
23546 res = false;
23548 out:
23549 free_filedata (filedata);
23551 free_debug_memory ();
23553 return res;
23556 /* Process an ELF archive.
23557 On entry the file is positioned just after the ARMAG string.
23558 Returns TRUE upon success, FALSE otherwise. */
23560 static bool
23561 process_archive (Filedata * filedata, bool is_thin_archive)
23563 struct archive_info arch;
23564 struct archive_info nested_arch;
23565 size_t got;
23566 bool ret = true;
23568 show_name = true;
23570 /* The ARCH structure is used to hold information about this archive. */
23571 arch.file_name = NULL;
23572 arch.file = NULL;
23573 arch.index_array = NULL;
23574 arch.sym_table = NULL;
23575 arch.longnames = NULL;
23577 /* The NESTED_ARCH structure is used as a single-item cache of information
23578 about a nested archive (when members of a thin archive reside within
23579 another regular archive file). */
23580 nested_arch.file_name = NULL;
23581 nested_arch.file = NULL;
23582 nested_arch.index_array = NULL;
23583 nested_arch.sym_table = NULL;
23584 nested_arch.longnames = NULL;
23586 if (setup_archive (&arch, filedata->file_name, filedata->handle,
23587 filedata->file_size, is_thin_archive,
23588 do_archive_index) != 0)
23590 ret = false;
23591 goto out;
23594 if (do_archive_index)
23596 if (arch.sym_table == NULL)
23597 error (_("%s: unable to dump the index as none was found\n"),
23598 filedata->file_name);
23599 else
23601 uint64_t i, l;
23602 uint64_t current_pos;
23604 printf (_("Index of archive %s: (%" PRIu64 " entries,"
23605 " %#" PRIx64 " bytes in the symbol table)\n"),
23606 filedata->file_name, arch.index_num,
23607 arch.sym_size);
23609 current_pos = ftell (filedata->handle);
23611 for (i = l = 0; i < arch.index_num; i++)
23613 if (i == 0
23614 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
23616 char * member_name
23617 = get_archive_member_name_at (&arch, arch.index_array[i],
23618 &nested_arch);
23620 if (member_name != NULL)
23622 char * qualified_name
23623 = make_qualified_name (&arch, &nested_arch,
23624 member_name);
23626 if (qualified_name != NULL)
23628 printf (_("Contents of binary %s at offset "),
23629 qualified_name);
23630 (void) print_vma (arch.index_array[i], PREFIX_HEX);
23631 putchar ('\n');
23632 free (qualified_name);
23634 free (member_name);
23638 if (l >= arch.sym_size)
23640 error (_("%s: end of the symbol table reached "
23641 "before the end of the index\n"),
23642 filedata->file_name);
23643 ret = false;
23644 break;
23646 /* PR 17531: file: 0b6630b2. */
23647 printf ("\t%.*s\n",
23648 (int) (arch.sym_size - l), arch.sym_table + l);
23649 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
23652 if (arch.uses_64bit_indices)
23653 l = (l + 7) & ~ 7;
23654 else
23655 l += l & 1;
23657 if (l < arch.sym_size)
23659 error (ngettext ("%s: %" PRId64 " byte remains in the symbol table, "
23660 "but without corresponding entries in "
23661 "the index table\n",
23662 "%s: %" PRId64 " bytes remain in the symbol table, "
23663 "but without corresponding entries in "
23664 "the index table\n",
23665 arch.sym_size - l),
23666 filedata->file_name, arch.sym_size - l);
23667 ret = false;
23670 if (fseek64 (filedata->handle, current_pos, SEEK_SET) != 0)
23672 error (_("%s: failed to seek back to start of object files "
23673 "in the archive\n"),
23674 filedata->file_name);
23675 ret = false;
23676 goto out;
23680 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
23681 && !do_segments && !do_header && !do_dump && !do_version
23682 && !do_histogram && !do_debugging && !do_arch && !do_notes
23683 && !do_section_groups && !do_dyn_syms)
23685 ret = true; /* Archive index only. */
23686 goto out;
23690 while (1)
23692 char * name;
23693 size_t namelen;
23694 char * qualified_name;
23696 /* Read the next archive header. */
23697 if (fseek64 (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
23699 error (_("%s: failed to seek to next archive header\n"),
23700 arch.file_name);
23701 ret = false;
23702 break;
23704 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
23705 if (got != sizeof arch.arhdr)
23707 if (got == 0)
23708 break;
23709 /* PR 24049 - we cannot use filedata->file_name as this will
23710 have already been freed. */
23711 error (_("%s: failed to read archive header\n"), arch.file_name);
23713 ret = false;
23714 break;
23716 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
23718 error (_("%s: did not find a valid archive header\n"),
23719 arch.file_name);
23720 ret = false;
23721 break;
23724 arch.next_arhdr_offset += sizeof arch.arhdr;
23726 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
23728 name = get_archive_member_name (&arch, &nested_arch);
23729 if (name == NULL)
23731 error (_("%s: bad archive file name\n"), arch.file_name);
23732 ret = false;
23733 break;
23735 namelen = strlen (name);
23737 qualified_name = make_qualified_name (&arch, &nested_arch, name);
23738 if (qualified_name == NULL)
23740 error (_("%s: bad archive file name\n"), arch.file_name);
23741 free (name);
23742 ret = false;
23743 break;
23746 if (is_thin_archive && arch.nested_member_origin == 0)
23748 /* This is a proxy for an external member of a thin archive. */
23749 Filedata * member_filedata;
23750 char * member_file_name = adjust_relative_path
23751 (filedata->file_name, name, namelen);
23753 free (name);
23754 if (member_file_name == NULL)
23756 free (qualified_name);
23757 ret = false;
23758 break;
23761 member_filedata = open_file (member_file_name, false);
23762 if (member_filedata == NULL)
23764 error (_("Input file '%s' is not readable.\n"), member_file_name);
23765 free (member_file_name);
23766 free (qualified_name);
23767 ret = false;
23768 break;
23771 filedata->archive_file_offset = arch.nested_member_origin;
23772 member_filedata->file_name = qualified_name;
23774 /* The call to process_object() expects the file to be at the beginning. */
23775 rewind (member_filedata->handle);
23777 if (! process_object (member_filedata))
23778 ret = false;
23780 close_file (member_filedata);
23781 free (member_file_name);
23783 else if (is_thin_archive)
23785 Filedata thin_filedata;
23787 memset (&thin_filedata, 0, sizeof (thin_filedata));
23789 /* PR 15140: Allow for corrupt thin archives. */
23790 if (nested_arch.file == NULL)
23792 error (_("%s: contains corrupt thin archive: %s\n"),
23793 qualified_name, name);
23794 free (qualified_name);
23795 free (name);
23796 ret = false;
23797 break;
23799 free (name);
23801 /* This is a proxy for a member of a nested archive. */
23802 filedata->archive_file_offset
23803 = arch.nested_member_origin + sizeof arch.arhdr;
23805 /* The nested archive file will have been opened and setup by
23806 get_archive_member_name. */
23807 if (fseek64 (nested_arch.file, filedata->archive_file_offset,
23808 SEEK_SET) != 0)
23810 error (_("%s: failed to seek to archive member.\n"),
23811 nested_arch.file_name);
23812 free (qualified_name);
23813 ret = false;
23814 break;
23817 thin_filedata.handle = nested_arch.file;
23818 thin_filedata.file_name = qualified_name;
23820 if (! process_object (& thin_filedata))
23821 ret = false;
23823 else
23825 free (name);
23826 filedata->archive_file_offset = arch.next_arhdr_offset;
23827 filedata->file_name = qualified_name;
23828 if (! process_object (filedata))
23829 ret = false;
23830 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
23831 /* Stop looping with "negative" archive_file_size. */
23832 if (arch.next_arhdr_offset < filedata->archive_file_size)
23833 arch.next_arhdr_offset = -1ul;
23836 free (qualified_name);
23839 out:
23840 if (nested_arch.file != NULL)
23841 fclose (nested_arch.file);
23842 release_archive (&nested_arch);
23843 release_archive (&arch);
23845 return ret;
23848 static bool
23849 process_file (char * file_name)
23851 Filedata * filedata = NULL;
23852 struct stat statbuf;
23853 char armag[SARMAG];
23854 bool ret = true;
23856 if (stat (file_name, &statbuf) < 0)
23858 if (errno == ENOENT)
23859 error (_("'%s': No such file\n"), file_name);
23860 else
23861 error (_("Could not locate '%s'. System error message: %s\n"),
23862 file_name, strerror (errno));
23863 return false;
23866 if (! S_ISREG (statbuf.st_mode))
23868 error (_("'%s' is not an ordinary file\n"), file_name);
23869 return false;
23872 filedata = calloc (1, sizeof * filedata);
23873 if (filedata == NULL)
23875 error (_("Out of memory allocating file data structure\n"));
23876 return false;
23879 filedata->file_name = file_name;
23880 filedata->handle = fopen (file_name, "rb");
23881 if (filedata->handle == NULL)
23883 error (_("Input file '%s' is not readable.\n"), file_name);
23884 free (filedata);
23885 return false;
23888 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
23890 error (_("%s: Failed to read file's magic number\n"), file_name);
23891 fclose (filedata->handle);
23892 free (filedata);
23893 return false;
23896 filedata->file_size = statbuf.st_size;
23897 filedata->is_separate = false;
23899 if (memcmp (armag, ARMAG, SARMAG) == 0)
23901 if (! process_archive (filedata, false))
23902 ret = false;
23904 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
23906 if ( ! process_archive (filedata, true))
23907 ret = false;
23909 else
23911 if (do_archive_index && !check_all)
23912 error (_("File %s is not an archive so its index cannot be displayed.\n"),
23913 file_name);
23915 rewind (filedata->handle);
23916 filedata->archive_file_size = filedata->archive_file_offset = 0;
23918 if (! process_object (filedata))
23919 ret = false;
23922 fclose (filedata->handle);
23923 free (filedata->section_headers);
23924 free (filedata->program_headers);
23925 free (filedata->string_table);
23926 free (filedata->dump.dump_sects);
23927 free (filedata);
23929 free (ba_cache.strtab);
23930 ba_cache.strtab = NULL;
23931 free (ba_cache.symtab);
23932 ba_cache.symtab = NULL;
23933 ba_cache.filedata = NULL;
23935 return ret;
23938 #ifdef SUPPORT_DISASSEMBLY
23939 /* Needed by the i386 disassembler. For extra credit, someone could
23940 fix this so that we insert symbolic addresses here, esp for GOT/PLT
23941 symbols. */
23943 void
23944 print_address (unsigned int addr, FILE * outfile)
23946 fprintf (outfile,"0x%8.8x", addr);
23949 /* Needed by the i386 disassembler. */
23951 void
23952 db_task_printsym (unsigned int addr)
23954 print_address (addr, stderr);
23956 #endif
23959 main (int argc, char ** argv)
23961 int err;
23963 #ifdef HAVE_LC_MESSAGES
23964 setlocale (LC_MESSAGES, "");
23965 #endif
23966 setlocale (LC_CTYPE, "");
23967 bindtextdomain (PACKAGE, LOCALEDIR);
23968 textdomain (PACKAGE);
23970 expandargv (&argc, &argv);
23972 parse_args (& cmdline, argc, argv);
23974 if (optind < (argc - 1))
23975 /* When displaying information for more than one file,
23976 prefix the information with the file name. */
23977 show_name = true;
23978 else if (optind >= argc)
23980 /* Ensure that the warning is always displayed. */
23981 do_checks = true;
23983 warn (_("Nothing to do.\n"));
23984 usage (stderr);
23987 err = false;
23988 while (optind < argc)
23989 if (! process_file (argv[optind++]))
23990 err = true;
23992 free (cmdline.dump_sects);
23994 free (dump_ctf_symtab_name);
23995 free (dump_ctf_strtab_name);
23996 free (dump_ctf_parent_name);
23998 return err ? EXIT_FAILURE : EXIT_SUCCESS;