19ee7876kaiw/*-
2aa01a21emaste * Copyright (c) 2009-2015 Kai Wang
39ee7876kaiw * All rights reserved.
49ee7876kaiw *
59ee7876kaiw * Redistribution and use in source and binary forms, with or without
69ee7876kaiw * modification, are permitted provided that the following conditions
79ee7876kaiw * are met:
89ee7876kaiw * 1. Redistributions of source code must retain the above copyright
99ee7876kaiw *    notice, this list of conditions and the following disclaimer.
109ee7876kaiw * 2. Redistributions in binary form must reproduce the above copyright
119ee7876kaiw *    notice, this list of conditions and the following disclaimer in the
129ee7876kaiw *    documentation and/or other materials provided with the distribution.
139ee7876kaiw *
149ee7876kaiw * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
159ee7876kaiw * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
169ee7876kaiw * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
179ee7876kaiw * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
189ee7876kaiw * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
199ee7876kaiw * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
209ee7876kaiw * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
219ee7876kaiw * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
229ee7876kaiw * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
239ee7876kaiw * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
249ee7876kaiw * SUCH DAMAGE.
259ee7876kaiw */
269ee7876kaiw
279ee7876kaiw#include <sys/param.h>
289ee7876kaiw#include <sys/queue.h>
29d797670markj
309ee7876kaiw#include <ar.h>
3106d81bdemaste#include <assert.h>
32d797670markj#include <capsicum_helpers.h>
339ee7876kaiw#include <ctype.h>
349ee7876kaiw#include <dwarf.h>
359ee7876kaiw#include <err.h>
369ee7876kaiw#include <fcntl.h>
379ee7876kaiw#include <gelf.h>
389ee7876kaiw#include <getopt.h>
399ee7876kaiw#include <libdwarf.h>
409ee7876kaiw#include <libelftc.h>
419ee7876kaiw#include <libgen.h>
429ee7876kaiw#include <stdarg.h>
43904cd98emaste#include <stdint.h>
449ee7876kaiw#include <stdio.h>
459ee7876kaiw#include <stdlib.h>
469ee7876kaiw#include <string.h>
479ee7876kaiw#include <time.h>
489ee7876kaiw#include <unistd.h>
499ee7876kaiw
50d797670markj#include <libcasper.h>
51d797670markj#include <casper/cap_fileargs.h>
52d797670markj
539ee7876kaiw#include "_elftc.h"
549ee7876kaiw
55061ef1femasteELFTC_VCSID("$Id: readelf.c 3769 2019-06-29 15:15:02Z emaste $");
569ee7876kaiw
57a6ae909emaste/* Backwards compatability for older FreeBSD releases. */
58a6ae909emaste#ifndef	STB_GNU_UNIQUE
59a6ae909emaste#define	STB_GNU_UNIQUE 10
60a6ae909emaste#endif
61a6ae909emaste#ifndef	STT_SPARC_REGISTER
62a6ae909emaste#define	STT_SPARC_REGISTER 13
63a6ae909emaste#endif
64a6ae909emaste
659ee7876kaiw
669ee7876kaiw/*
679ee7876kaiw * readelf(1) options.
689ee7876kaiw */
699ee7876kaiw#define	RE_AA	0x00000001
709ee7876kaiw#define	RE_C	0x00000002
719ee7876kaiw#define	RE_DD	0x00000004
729ee7876kaiw#define	RE_D	0x00000008
739ee7876kaiw#define	RE_G	0x00000010
749ee7876kaiw#define	RE_H	0x00000020
759ee7876kaiw#define	RE_II	0x00000040
769ee7876kaiw#define	RE_I	0x00000080
779ee7876kaiw#define	RE_L	0x00000100
789ee7876kaiw#define	RE_NN	0x00000200
799ee7876kaiw#define	RE_N	0x00000400
809ee7876kaiw#define	RE_P	0x00000800
819ee7876kaiw#define	RE_R	0x00001000
829ee7876kaiw#define	RE_SS	0x00002000
839ee7876kaiw#define	RE_S	0x00004000
849ee7876kaiw#define	RE_T	0x00008000
859ee7876kaiw#define	RE_U	0x00010000
869ee7876kaiw#define	RE_VV	0x00020000
879ee7876kaiw#define	RE_WW	0x00040000
889ee7876kaiw#define	RE_W	0x00080000
899ee7876kaiw#define	RE_X	0x00100000
909ee7876kaiw
919ee7876kaiw/*
929ee7876kaiw * dwarf dump options.
939ee7876kaiw */
949ee7876kaiw#define	DW_A	0x00000001
959ee7876kaiw#define	DW_FF	0x00000002
969ee7876kaiw#define	DW_F	0x00000004
979ee7876kaiw#define	DW_I	0x00000008
989ee7876kaiw#define	DW_LL	0x00000010
999ee7876kaiw#define	DW_L	0x00000020
1009ee7876kaiw#define	DW_M	0x00000040
1019ee7876kaiw#define	DW_O	0x00000080
1029ee7876kaiw#define	DW_P	0x00000100
1039ee7876kaiw#define	DW_RR	0x00000200
1049ee7876kaiw#define	DW_R	0x00000400
1059ee7876kaiw#define	DW_S	0x00000800
1069ee7876kaiw
1079ee7876kaiw#define	DW_DEFAULT_OPTIONS (DW_A | DW_F | DW_I | DW_L | DW_O | DW_P | \
1089ee7876kaiw	    DW_R | DW_RR | DW_S)
1099ee7876kaiw
1109ee7876kaiw/*
1119ee7876kaiw * readelf(1) run control flags.
1129ee7876kaiw */
1139ee7876kaiw#define	DISPLAY_FILENAME	0x0001
1149ee7876kaiw
1159ee7876kaiw/*
1169ee7876kaiw * Internal data structure for sections.
1179ee7876kaiw */
1189ee7876kaiwstruct section {
1199ee7876kaiw	const char	*name;		/* section name */
1209ee7876kaiw	Elf_Scn		*scn;		/* section scn */
1219ee7876kaiw	uint64_t	 off;		/* section offset */
1229ee7876kaiw	uint64_t	 sz;		/* section size */
1239ee7876kaiw	uint64_t	 entsize;	/* section entsize */
1249ee7876kaiw	uint64_t	 align;		/* section alignment */
1259ee7876kaiw	uint64_t	 type;		/* section type */
1269ee7876kaiw	uint64_t	 flags;		/* section flags */
1279ee7876kaiw	uint64_t	 addr;		/* section virtual addr */
1289ee7876kaiw	uint32_t	 link;		/* section link ndx */
1299ee7876kaiw	uint32_t	 info;		/* section info ndx */
1309ee7876kaiw};
1319ee7876kaiw
1329ee7876kaiwstruct dumpop {
1339ee7876kaiw	union {
1349ee7876kaiw		size_t si;		/* section index */
1359ee7876kaiw		const char *sn;		/* section name */
1369ee7876kaiw	} u;
1379ee7876kaiw	enum {
1389ee7876kaiw		DUMP_BY_INDEX = 0,
1399ee7876kaiw		DUMP_BY_NAME
1409ee7876kaiw	} type;				/* dump type */
1419ee7876kaiw#define HEX_DUMP	0x0001
1429ee7876kaiw#define STR_DUMP	0x0002
1439ee7876kaiw	int op;				/* dump operation */
1449ee7876kaiw	STAILQ_ENTRY(dumpop) dumpop_list;
1459ee7876kaiw};
1469ee7876kaiw
1479ee7876kaiwstruct symver {
1489ee7876kaiw	const char *name;
1499ee7876kaiw	int type;
1509ee7876kaiw};
1519ee7876kaiw
1529ee7876kaiw/*
1539ee7876kaiw * Structure encapsulates the global data for readelf(1).
1549ee7876kaiw */
1559ee7876kaiwstruct readelf {
1569ee7876kaiw	const char	 *filename;	/* current processing file. */
1579ee7876kaiw	int		  options;	/* command line options. */
1589ee7876kaiw	int		  flags;	/* run control flags. */
1599ee7876kaiw	int		  dop;		/* dwarf dump options. */
1609ee7876kaiw	Elf		 *elf;		/* underlying ELF descriptor. */
1619ee7876kaiw	Elf		 *ar;		/* archive ELF descriptor. */
1629ee7876kaiw	Dwarf_Debug	  dbg;		/* DWARF handle. */
163a9e16ddemaste	Dwarf_Half	  cu_psize;	/* DWARF CU pointer size. */
164a9e16ddemaste	Dwarf_Half	  cu_osize;	/* DWARF CU offset size. */
165a9e16ddemaste	Dwarf_Half	  cu_ver;	/* DWARF CU version. */
1669ee7876kaiw	GElf_Ehdr	  ehdr;		/* ELF header. */
1679ee7876kaiw	int		  ec;		/* ELF class. */
1689ee7876kaiw	size_t		  shnum;	/* #sections. */
1699ee7876kaiw	struct section	 *vd_s;		/* Verdef section. */
1709ee7876kaiw	struct section	 *vn_s;		/* Verneed section. */
1719ee7876kaiw	struct section	 *vs_s;		/* Versym section. */
1729ee7876kaiw	uint16_t	 *vs;		/* Versym array. */
1739ee7876kaiw	int		  vs_sz;	/* Versym array size. */
1749ee7876kaiw	struct symver	 *ver;		/* Version array. */
1759ee7876kaiw	int		  ver_sz;	/* Size of version array. */
1769ee7876kaiw	struct section	 *sl;		/* list of sections. */
1779ee7876kaiw	STAILQ_HEAD(, dumpop) v_dumpop; /* list of dump ops. */
1789ee7876kaiw	uint64_t	(*dw_read)(Elf_Data *, uint64_t *, int);
1799ee7876kaiw	uint64_t	(*dw_decode)(uint8_t **, int);
1809ee7876kaiw};
1819ee7876kaiw
1829ee7876kaiwenum options
1839ee7876kaiw{
1849ee7876kaiw	OPTION_DEBUG_DUMP
1859ee7876kaiw};
1869ee7876kaiw
1879ee7876kaiwstatic struct option longopts[] = {
1889ee7876kaiw	{"all", no_argument, NULL, 'a'},
1899ee7876kaiw	{"arch-specific", no_argument, NULL, 'A'},
1909ee7876kaiw	{"archive-index", no_argument, NULL, 'c'},
1919ee7876kaiw	{"debug-dump", optional_argument, NULL, OPTION_DEBUG_DUMP},
1929ee7876kaiw	{"dynamic", no_argument, NULL, 'd'},
1939ee7876kaiw	{"file-header", no_argument, NULL, 'h'},
1949ee7876kaiw	{"full-section-name", no_argument, NULL, 'N'},
1959ee7876kaiw	{"headers", no_argument, NULL, 'e'},
1969ee7876kaiw	{"help", no_argument, 0, 'H'},
1979ee7876kaiw	{"hex-dump", required_argument, NULL, 'x'},
1989ee7876kaiw	{"histogram", no_argument, NULL, 'I'},
1999ee7876kaiw	{"notes", no_argument, NULL, 'n'},
2009ee7876kaiw	{"program-headers", no_argument, NULL, 'l'},
2019ee7876kaiw	{"relocs", no_argument, NULL, 'r'},
2029ee7876kaiw	{"sections", no_argument, NULL, 'S'},
2039ee7876kaiw	{"section-headers", no_argument, NULL, 'S'},
2049ee7876kaiw	{"section-groups", no_argument, NULL, 'g'},
2059ee7876kaiw	{"section-details", no_argument, NULL, 't'},
2069ee7876kaiw	{"segments", no_argument, NULL, 'l'},
2079ee7876kaiw	{"string-dump", required_argument, NULL, 'p'},
2089ee7876kaiw	{"symbols", no_argument, NULL, 's'},
2099ee7876kaiw	{"syms", no_argument, NULL, 's'},
2109ee7876kaiw	{"unwind", no_argument, NULL, 'u'},
2119ee7876kaiw	{"use-dynamic", no_argument, NULL, 'D'},
2129ee7876kaiw	{"version-info", no_argument, 0, 'V'},
2139ee7876kaiw	{"version", no_argument, 0, 'v'},
2149ee7876kaiw	{"wide", no_argument, 0, 'W'},
2159ee7876kaiw	{NULL, 0, NULL, 0}
2169ee7876kaiw};
2179ee7876kaiw
2189ee7876kaiwstruct eflags_desc {
2199ee7876kaiw	uint64_t flag;
2209ee7876kaiw	const char *desc;
2219ee7876kaiw};
2229ee7876kaiw
223061ef1femastestruct flag_desc {
2249ee7876kaiw	uint64_t flag;
2259ee7876kaiw	const char *desc;
2269ee7876kaiw};
2279ee7876kaiw
2289ee7876kaiwstruct mips_option {
229ab08890emaste	uint64_t flag;
230ab08890emaste	const char *desc;
231ab08890emaste};
232ab08890emaste
2336f62c92emastestruct loc_at {
2346f62c92emaste	Dwarf_Attribute la_at;
2356f62c92emaste	Dwarf_Unsigned la_off;
2366f62c92emaste	Dwarf_Unsigned la_lowpc;
2376f62c92emaste	Dwarf_Half la_cu_psize;
2386f62c92emaste	Dwarf_Half la_cu_osize;
2396f62c92emaste	Dwarf_Half la_cu_ver;
2406f62c92emaste};
2416f62c92emaste
2429ee7876kaiwstatic void add_dumpop(struct readelf *re, size_t si, const char *sn, int op,
2439ee7876kaiw    int t);
2449ee7876kaiwstatic const char *aeabi_adv_simd_arch(uint64_t simd);
2459ee7876kaiwstatic const char *aeabi_align_needed(uint64_t an);
2469ee7876kaiwstatic const char *aeabi_align_preserved(uint64_t ap);
2479ee7876kaiwstatic const char *aeabi_arm_isa(uint64_t ai);
2489ee7876kaiwstatic const char *aeabi_cpu_arch(uint64_t arch);
2499ee7876kaiwstatic const char *aeabi_cpu_arch_profile(uint64_t pf);
2509ee7876kaiwstatic const char *aeabi_div(uint64_t du);
2519ee7876kaiwstatic const char *aeabi_enum_size(uint64_t es);
2529ee7876kaiwstatic const char *aeabi_fp_16bit_format(uint64_t fp16);
2539ee7876kaiwstatic const char *aeabi_fp_arch(uint64_t fp);
2549ee7876kaiwstatic const char *aeabi_fp_denormal(uint64_t fd);
2559ee7876kaiwstatic const char *aeabi_fp_exceptions(uint64_t fe);
2569ee7876kaiwstatic const char *aeabi_fp_hpext(uint64_t fh);
2579ee7876kaiwstatic const char *aeabi_fp_number_model(uint64_t fn);
2589ee7876kaiwstatic const char *aeabi_fp_optm_goal(uint64_t fog);
2599ee7876kaiwstatic const char *aeabi_fp_rounding(uint64_t fr);
2609ee7876kaiwstatic const char *aeabi_hardfp(uint64_t hfp);
2619ee7876kaiwstatic const char *aeabi_mpext(uint64_t mp);
2629ee7876kaiwstatic const char *aeabi_optm_goal(uint64_t og);
2639ee7876kaiwstatic const char *aeabi_pcs_config(uint64_t pcs);
2649ee7876kaiwstatic const char *aeabi_pcs_got(uint64_t got);
2659ee7876kaiwstatic const char *aeabi_pcs_r9(uint64_t r9);
2669ee7876kaiwstatic const char *aeabi_pcs_ro(uint64_t ro);
2679ee7876kaiwstatic const char *aeabi_pcs_rw(uint64_t rw);
2689ee7876kaiwstatic const char *aeabi_pcs_wchar_t(uint64_t wt);
2699ee7876kaiwstatic const char *aeabi_t2ee(uint64_t t2ee);
2709ee7876kaiwstatic const char *aeabi_thumb_isa(uint64_t ti);
2719ee7876kaiwstatic const char *aeabi_fp_user_exceptions(uint64_t fu);
2729ee7876kaiwstatic const char *aeabi_unaligned_access(uint64_t ua);
2739ee7876kaiwstatic const char *aeabi_vfp_args(uint64_t va);
2749ee7876kaiwstatic const char *aeabi_virtual(uint64_t vt);
2759ee7876kaiwstatic const char *aeabi_wmmx_arch(uint64_t wmmx);
2769ee7876kaiwstatic const char *aeabi_wmmx_args(uint64_t wa);
2779ee7876kaiwstatic const char *elf_class(unsigned int class);
2789ee7876kaiwstatic const char *elf_endian(unsigned int endian);
2799ee7876kaiwstatic const char *elf_machine(unsigned int mach);
2809ee7876kaiwstatic const char *elf_osabi(unsigned int abi);
2819ee7876kaiwstatic const char *elf_type(unsigned int type);
2829ee7876kaiwstatic const char *elf_ver(unsigned int ver);
2839ee7876kaiwstatic const char *dt_type(unsigned int mach, unsigned int dtype);
2849ee7876kaiwstatic void dump_ar(struct readelf *re, int);
2859ee7876kaiwstatic void dump_arm_attributes(struct readelf *re, uint8_t *p, uint8_t *pe);
2869ee7876kaiwstatic void dump_attributes(struct readelf *re);
2878d8726eemastestatic uint8_t *dump_compatibility_tag(uint8_t *p, uint8_t *pe);
2889ee7876kaiwstatic void dump_dwarf(struct readelf *re);
289a9e16ddemastestatic void dump_dwarf_abbrev(struct readelf *re);
290a9e16ddemastestatic void dump_dwarf_aranges(struct readelf *re);
291a9e16ddemastestatic void dump_dwarf_block(struct readelf *re, uint8_t *b,
292a9e16ddemaste    Dwarf_Unsigned len);
293a9e16ddemastestatic void dump_dwarf_die(struct readelf *re, Dwarf_Die die, int level);
294a9e16ddemastestatic void dump_dwarf_frame(struct readelf *re, int alt);
295a9e16ddemastestatic void dump_dwarf_frame_inst(struct readelf *re, Dwarf_Cie cie,
296a9e16ddemaste    uint8_t *insts, Dwarf_Unsigned len, Dwarf_Unsigned caf, Dwarf_Signed daf,
297a9e16ddemaste    Dwarf_Addr pc, Dwarf_Debug dbg);
298a9e16ddemastestatic int dump_dwarf_frame_regtable(struct readelf *re, Dwarf_Fde fde,
299a9e16ddemaste    Dwarf_Addr pc, Dwarf_Unsigned func_len, Dwarf_Half cie_ra);
300a9e16ddemastestatic void dump_dwarf_frame_section(struct readelf *re, struct section *s,
301a9e16ddemaste    int alt);
302a9e16ddemastestatic void dump_dwarf_info(struct readelf *re, Dwarf_Bool is_info);
303a9e16ddemastestatic void dump_dwarf_macinfo(struct readelf *re);
304a9e16ddemastestatic void dump_dwarf_line(struct readelf *re);
305a9e16ddemastestatic void dump_dwarf_line_decoded(struct readelf *re);
306a9e16ddemastestatic void dump_dwarf_loc(struct readelf *re, Dwarf_Loc *lr);
307a9e16ddemastestatic void dump_dwarf_loclist(struct readelf *re);
308a9e16ddemastestatic void dump_dwarf_pubnames(struct readelf *re);
309a9e16ddemastestatic void dump_dwarf_ranges(struct readelf *re);
310a9e16ddemastestatic void dump_dwarf_ranges_foreach(struct readelf *re, Dwarf_Die die,
311a9e16ddemaste    Dwarf_Addr base);
312a9e16ddemastestatic void dump_dwarf_str(struct readelf *re);
3139ee7876kaiwstatic void dump_eflags(struct readelf *re, uint64_t e_flags);
3149ee7876kaiwstatic void dump_elf(struct readelf *re);
315ab08890emastestatic void dump_flags(struct flag_desc *fd, uint64_t flags);
3169ee7876kaiwstatic void dump_dyn_val(struct readelf *re, GElf_Dyn *dyn, uint32_t stab);
3179ee7876kaiwstatic void dump_dynamic(struct readelf *re);
3189ee7876kaiwstatic void dump_liblist(struct readelf *re);
319a0953c0emastestatic void dump_mips_abiflags(struct readelf *re, struct section *s);
3209ee7876kaiwstatic void dump_mips_attributes(struct readelf *re, uint8_t *p, uint8_t *pe);
3219ee7876kaiwstatic void dump_mips_odk_reginfo(struct readelf *re, uint8_t *p, size_t sz);
3229ee7876kaiwstatic void dump_mips_options(struct readelf *re, struct section *s);
3239ee7876kaiwstatic void dump_mips_option_flags(const char *name, struct mips_option *opt,
3249ee7876kaiw    uint64_t info);
3259ee7876kaiwstatic void dump_mips_reginfo(struct readelf *re, struct section *s);
3269ee7876kaiwstatic void dump_mips_specific_info(struct readelf *re);
3279ee7876kaiwstatic void dump_notes(struct readelf *re);
3289ee7876kaiwstatic void dump_notes_content(struct readelf *re, const char *buf, size_t sz,
3299ee7876kaiw    off_t off);
3303b2bdd0emastestatic void dump_notes_data(struct readelf *re, const char *name,
3313b2bdd0emaste    uint32_t type, const char *buf, size_t sz);
3329ee7876kaiwstatic void dump_svr4_hash(struct section *s);
3339ee7876kaiwstatic void dump_svr4_hash64(struct readelf *re, struct section *s);
3349ee7876kaiwstatic void dump_gnu_hash(struct readelf *re, struct section *s);
3353b2bdd0emastestatic void dump_gnu_property_type_0(struct readelf *re, const char *buf,
3363b2bdd0emaste    size_t sz);
3379ee7876kaiwstatic void dump_hash(struct readelf *re);
3389ee7876kaiwstatic void dump_phdr(struct readelf *re);
3399ee7876kaiwstatic void dump_ppc_attributes(uint8_t *p, uint8_t *pe);
340aa01a21emastestatic void dump_section_groups(struct readelf *re);
3419ee7876kaiwstatic void dump_symtab(struct readelf *re, int i);
3429ee7876kaiwstatic void dump_symtabs(struct readelf *re);
3438d8726eemastestatic uint8_t *dump_unknown_tag(uint64_t tag, uint8_t *p, uint8_t *pe);
3449ee7876kaiwstatic void dump_ver(struct readelf *re);
3459ee7876kaiwstatic void dump_verdef(struct readelf *re, int dump);
3469ee7876kaiwstatic void dump_verneed(struct readelf *re, int dump);
3479ee7876kaiwstatic void dump_versym(struct readelf *re);
348a9e16ddemastestatic const char *dwarf_reg(unsigned int mach, unsigned int reg);
349a9e16ddemastestatic const char *dwarf_regname(struct readelf *re, unsigned int num);
350a9e16ddemastestatic struct dumpop *find_dumpop(struct readelf *re, size_t si,
351a9e16ddemaste    const char *sn, int op, int t);
35206d81bdemastestatic int get_ent_count(struct section *s, int *ent_count);
353a0953c0emastestatic int get_mips_register_size(uint8_t flag);
354a9e16ddemastestatic char *get_regoff_str(struct readelf *re, Dwarf_Half reg,
355a9e16ddemaste    Dwarf_Addr off);
3569ee7876kaiwstatic const char *get_string(struct readelf *re, int strtab, size_t off);
3579ee7876kaiwstatic const char *get_symbol_name(struct readelf *re, int symtab, int i);
3589ee7876kaiwstatic uint64_t get_symbol_value(struct readelf *re, int symtab, int i);
3599ee7876kaiwstatic void load_sections(struct readelf *re);
3606f62c92emastestatic int loc_at_comparator(const void *la1, const void *la2);
3619ee7876kaiwstatic const char *mips_abi_fp(uint64_t fp);
362e016e1femastestatic const char *note_type(const char *note_name, unsigned int et,
3639ee7876kaiw    unsigned int nt);
364e016e1femastestatic const char *note_type_freebsd(unsigned int nt);
365e016e1femastestatic const char *note_type_freebsd_core(unsigned int nt);
366e016e1femastestatic const char *note_type_linux_core(unsigned int nt);
367e016e1femastestatic const char *note_type_gnu(unsigned int nt);
368e016e1femastestatic const char *note_type_netbsd(unsigned int nt);
369e016e1femastestatic const char *note_type_openbsd(unsigned int nt);
370e016e1femastestatic const char *note_type_unknown(unsigned int nt);
3717e478f4emastestatic const char *note_type_xen(unsigned int nt);
3729ee7876kaiwstatic const char *option_kind(uint8_t kind);
373d9111a9emastestatic const char *phdr_type(unsigned int mach, unsigned int ptype);
3749ee7876kaiwstatic const char *ppc_abi_fp(uint64_t fp);
3759ee7876kaiwstatic const char *ppc_abi_vector(uint64_t vec);
37685217deemastestatic void readelf_usage(int status);
3779ee7876kaiwstatic void readelf_version(void);
378a9e16ddemastestatic void search_loclist_at(struct readelf *re, Dwarf_Die die,
3796f62c92emaste    Dwarf_Unsigned lowpc, struct loc_at **la_list,
380ee93d86emaste    size_t *la_list_len, size_t *la_list_cap);
3819ee7876kaiwstatic void search_ver(struct readelf *re);
3829ee7876kaiwstatic const char *section_type(unsigned int mach, unsigned int stype);
383a9e16ddemastestatic void set_cu_context(struct readelf *re, Dwarf_Half psize,
384a9e16ddemaste    Dwarf_Half osize, Dwarf_Half ver);
3859ee7876kaiwstatic const char *st_bind(unsigned int sbind);
3869ee7876kaiwstatic const char *st_shndx(unsigned int shndx);
387db27a04emastestatic const char *st_type(unsigned int mach, unsigned int os,
388db27a04emaste    unsigned int stype);
3899ee7876kaiwstatic const char *st_vis(unsigned int svis);
3909ee7876kaiwstatic const char *top_tag(unsigned int tag);
3919ee7876kaiwstatic void unload_sections(struct readelf *re);
3929ee7876kaiwstatic uint64_t _read_lsb(Elf_Data *d, uint64_t *offsetp,
3939ee7876kaiw    int bytes_to_read);
3949ee7876kaiwstatic uint64_t _read_msb(Elf_Data *d, uint64_t *offsetp,
3959ee7876kaiw    int bytes_to_read);
3969ee7876kaiwstatic uint64_t _decode_lsb(uint8_t **data, int bytes_to_read);
3979ee7876kaiwstatic uint64_t _decode_msb(uint8_t **data, int bytes_to_read);
3988d8726eemastestatic int64_t _decode_sleb128(uint8_t **dp, uint8_t *dpe);
3998d8726eemastestatic uint64_t _decode_uleb128(uint8_t **dp, uint8_t *dpe);
4009ee7876kaiw
4019ee7876kaiwstatic struct eflags_desc arm_eflags_desc[] = {
4029ee7876kaiw	{EF_ARM_RELEXEC, "relocatable executable"},
4039ee7876kaiw	{EF_ARM_HASENTRY, "has entry point"},
4049ee7876kaiw	{EF_ARM_SYMSARESORTED, "sorted symbol tables"},
4059ee7876kaiw	{EF_ARM_DYNSYMSUSESEGIDX, "dynamic symbols use segment index"},
4069ee7876kaiw	{EF_ARM_MAPSYMSFIRST, "mapping symbols precede others"},
4079ee7876kaiw	{EF_ARM_BE8, "BE8"},
4089ee7876kaiw	{EF_ARM_LE8, "LE8"},
4099ee7876kaiw	{EF_ARM_INTERWORK, "interworking enabled"},
4109ee7876kaiw	{EF_ARM_APCS_26, "uses APCS/26"},
4119ee7876kaiw	{EF_ARM_APCS_FLOAT, "uses APCS/float"},
4129ee7876kaiw	{EF_ARM_PIC, "position independent"},
4139ee7876kaiw	{EF_ARM_ALIGN8, "8 bit structure alignment"},
4149ee7876kaiw	{EF_ARM_NEW_ABI, "uses new ABI"},
4159ee7876kaiw	{EF_ARM_OLD_ABI, "uses old ABI"},
4169ee7876kaiw	{EF_ARM_SOFT_FLOAT, "software FP"},
4179ee7876kaiw	{EF_ARM_VFP_FLOAT, "VFP"},
4189ee7876kaiw	{EF_ARM_MAVERICK_FLOAT, "Maverick FP"},
4199ee7876kaiw	{0, NULL}
4209ee7876kaiw};
4219ee7876kaiw
4229ee7876kaiwstatic struct eflags_desc mips_eflags_desc[] = {
4239ee7876kaiw	{EF_MIPS_NOREORDER, "noreorder"},
4249ee7876kaiw	{EF_MIPS_PIC, "pic"},
4259ee7876kaiw	{EF_MIPS_CPIC, "cpic"},
4269ee7876kaiw	{EF_MIPS_UCODE, "ugen_reserved"},
4279ee7876kaiw	{EF_MIPS_ABI2, "abi2"},
4289ee7876kaiw	{EF_MIPS_OPTIONS_FIRST, "odk first"},
4299ee7876kaiw	{EF_MIPS_ARCH_ASE_MDMX, "mdmx"},
4309ee7876kaiw	{EF_MIPS_ARCH_ASE_M16, "mips16"},
4319ee7876kaiw	{0, NULL}
4329ee7876kaiw};
4339ee7876kaiw
4349ee7876kaiwstatic struct eflags_desc powerpc_eflags_desc[] = {
4359ee7876kaiw	{EF_PPC_EMB, "emb"},
4369ee7876kaiw	{EF_PPC_RELOCATABLE, "relocatable"},
4379ee7876kaiw	{EF_PPC_RELOCATABLE_LIB, "relocatable-lib"},
4389ee7876kaiw	{0, NULL}
4399ee7876kaiw};
4409ee7876kaiw
44186dfd2fmhornestatic struct eflags_desc riscv_eflags_desc[] = {
44286dfd2fmhorne	{EF_RISCV_RVC, "RVC"},
44386dfd2fmhorne	{EF_RISCV_RVE, "RVE"},
44486dfd2fmhorne	{EF_RISCV_TSO, "TSO"},
44586dfd2fmhorne	{0, NULL}
44686dfd2fmhorne};
44786dfd2fmhorne
4489ee7876kaiwstatic struct eflags_desc sparc_eflags_desc[] = {
4499ee7876kaiw	{EF_SPARC_32PLUS, "v8+"},
4509ee7876kaiw	{EF_SPARC_SUN_US1, "ultrasparcI"},
4519ee7876kaiw	{EF_SPARC_HAL_R1, "halr1"},
4529ee7876kaiw	{EF_SPARC_SUN_US3, "ultrasparcIII"},
4539ee7876kaiw	{0, NULL}
4549ee7876kaiw};
4559ee7876kaiw
4569ee7876kaiwstatic const char *
4579ee7876kaiwelf_osabi(unsigned int abi)
4589ee7876kaiw{
4599ee7876kaiw	static char s_abi[32];
4609ee7876kaiw
4619ee7876kaiw	switch(abi) {
46247a49e1emaste	case ELFOSABI_NONE: return "NONE";
463aed1daeemaste	case ELFOSABI_HPUX: return "HPUX";
4649ee7876kaiw	case ELFOSABI_NETBSD: return "NetBSD";
4659ee7876kaiw	case ELFOSABI_GNU: return "GNU";
4669ee7876kaiw	case ELFOSABI_HURD: return "HURD";
4679ee7876kaiw	case ELFOSABI_86OPEN: return "86OPEN";
4689ee7876kaiw	case ELFOSABI_SOLARIS: return "Solaris";
4699ee7876kaiw	case ELFOSABI_AIX: return "AIX";
4709ee7876kaiw	case ELFOSABI_IRIX: return "IRIX";
4719ee7876kaiw	case ELFOSABI_FREEBSD: return "FreeBSD";
4729ee7876kaiw	case ELFOSABI_TRU64: return "TRU64";
4739ee7876kaiw	case ELFOSABI_MODESTO: return "MODESTO";
4749ee7876kaiw	case ELFOSABI_OPENBSD: return "OpenBSD";
4759ee7876kaiw	case ELFOSABI_OPENVMS: return "OpenVMS";
4769ee7876kaiw	case ELFOSABI_NSK: return "NSK";
477db27a04emaste	case ELFOSABI_CLOUDABI: return "CloudABI";
4788c25ed7emaste	case ELFOSABI_ARM_AEABI: return "ARM EABI";
4799ee7876kaiw	case ELFOSABI_ARM: return "ARM";
4809ee7876kaiw	case ELFOSABI_STANDALONE: return "StandAlone";
4819ee7876kaiw	default:
4829ee7876kaiw		snprintf(s_abi, sizeof(s_abi), "<unknown: %#x>", abi);
4839ee7876kaiw		return (s_abi);
4849ee7876kaiw	}
4859ee7876kaiw};
4869ee7876kaiw
4879ee7876kaiwstatic const char *
4889ee7876kaiwelf_machine(unsigned int mach)
4899ee7876kaiw{
4909ee7876kaiw	static char s_mach[32];
4919ee7876kaiw
4929ee7876kaiw	switch (mach) {
4939ee7876kaiw	case EM_NONE: return "Unknown machine";
4949ee7876kaiw	case EM_M32: return "AT&T WE32100";
4959ee7876kaiw	case EM_SPARC: return "Sun SPARC";
4969ee7876kaiw	case EM_386: return "Intel i386";
4979ee7876kaiw	case EM_68K: return "Motorola 68000";
498aa01a21emaste	case EM_IAMCU: return "Intel MCU";
4999ee7876kaiw	case EM_88K: return "Motorola 88000";
5009ee7876kaiw	case EM_860: return "Intel i860";
5019ee7876kaiw	case EM_MIPS: return "MIPS R3000 Big-Endian only";
5029ee7876kaiw	case EM_S370: return "IBM System/370";
5039ee7876kaiw	case EM_MIPS_RS3_LE: return "MIPS R3000 Little-Endian";
5049ee7876kaiw	case EM_PARISC: return "HP PA-RISC";
5059ee7876kaiw	case EM_VPP500: return "Fujitsu VPP500";
5069ee7876kaiw	case EM_SPARC32PLUS: return "SPARC v8plus";
5079ee7876kaiw	case EM_960: return "Intel 80960";
5089ee7876kaiw	case EM_PPC: return "PowerPC 32-bit";
5099ee7876kaiw	case EM_PPC64: return "PowerPC 64-bit";
5109ee7876kaiw	case EM_S390: return "IBM System/390";
5119ee7876kaiw	case EM_V800: return "NEC V800";
5129ee7876kaiw	case EM_FR20: return "Fujitsu FR20";
5139ee7876kaiw	case EM_RH32: return "TRW RH-32";
5149ee7876kaiw	case EM_RCE: return "Motorola RCE";
5159ee7876kaiw	case EM_ARM: return "ARM";
5169ee7876kaiw	case EM_SH: return "Hitachi SH";
5179ee7876kaiw	case EM_SPARCV9: return "SPARC v9 64-bit";
5189ee7876kaiw	case EM_TRICORE: return "Siemens TriCore embedded processor";
5199ee7876kaiw	case EM_ARC: return "Argonaut RISC Core";
5209ee7876kaiw	case EM_H8_300: return "Hitachi H8/300";
5219ee7876kaiw	case EM_H8_300H: return "Hitachi H8/300H";
5229ee7876kaiw	case EM_H8S: return "Hitachi H8S";
5239ee7876kaiw	case EM_H8_500: return "Hitachi H8/500";
5249ee7876kaiw	case EM_IA_64: return "Intel IA-64 Processor";
5259ee7876kaiw	case EM_MIPS_X: return "Stanford MIPS-X";
5269ee7876kaiw	case EM_COLDFIRE: return "Motorola ColdFire";
5279ee7876kaiw	case EM_68HC12: return "Motorola M68HC12";
5289ee7876kaiw	case EM_MMA: return "Fujitsu MMA";
5299ee7876kaiw	case EM_PCP: return "Siemens PCP";
5309ee7876kaiw	case EM_NCPU: return "Sony nCPU";
5319ee7876kaiw	case EM_NDR1: return "Denso NDR1 microprocessor";
5329ee7876kaiw	case EM_STARCORE: return "Motorola Star*Core processor";
5339ee7876kaiw	case EM_ME16: return "Toyota ME16 processor";
5349ee7876kaiw	case EM_ST100: return "STMicroelectronics ST100 processor";
5359ee7876kaiw	case EM_TINYJ: return "Advanced Logic Corp. TinyJ processor";
5369ee7876kaiw	case EM_X86_64: return "Advanced Micro Devices x86-64";
5379ee7876kaiw	case EM_PDSP: return "Sony DSP Processor";
5389ee7876kaiw	case EM_FX66: return "Siemens FX66 microcontroller";
5399ee7876kaiw	case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 microcontroller";
5409ee7876kaiw	case EM_ST7: return "STmicroelectronics ST7 8-bit microcontroller";
5419ee7876kaiw	case EM_68HC16: return "Motorola MC68HC16 microcontroller";
5429ee7876kaiw	case EM_68HC11: return "Motorola MC68HC11 microcontroller";
5439ee7876kaiw	case EM_68HC08: return "Motorola MC68HC08 microcontroller";
5449ee7876kaiw	case EM_68HC05: return "Motorola MC68HC05 microcontroller";
5459ee7876kaiw	case EM_SVX: return "Silicon Graphics SVx";
5469ee7876kaiw	case EM_ST19: return "STMicroelectronics ST19 8-bit mc";
5479ee7876kaiw	case EM_VAX: return "Digital VAX";
5489ee7876kaiw	case EM_CRIS: return "Axis Communications 32-bit embedded processor";
5499ee7876kaiw	case EM_JAVELIN: return "Infineon Tech. 32bit embedded processor";
5509ee7876kaiw	case EM_FIREPATH: return "Element 14 64-bit DSP Processor";
5519ee7876kaiw	case EM_ZSP: return "LSI Logic 16-bit DSP Processor";
5529ee7876kaiw	case EM_MMIX: return "Donald Knuth's educational 64-bit proc";
5539ee7876kaiw	case EM_HUANY: return "Harvard University MI object files";
5549ee7876kaiw	case EM_PRISM: return "SiTera Prism";
5559ee7876kaiw	case EM_AVR: return "Atmel AVR 8-bit microcontroller";
5569ee7876kaiw	case EM_FR30: return "Fujitsu FR30";
5579ee7876kaiw	case EM_D10V: return "Mitsubishi D10V";
5589ee7876kaiw	case EM_D30V: return "Mitsubishi D30V";
5599ee7876kaiw	case EM_V850: return "NEC v850";
5609ee7876kaiw	case EM_M32R: return "Mitsubishi M32R";
5619ee7876kaiw	case EM_MN10300: return "Matsushita MN10300";
5629ee7876kaiw	case EM_MN10200: return "Matsushita MN10200";
5639ee7876kaiw	case EM_PJ: return "picoJava";
5649ee7876kaiw	case EM_OPENRISC: return "OpenRISC 32-bit embedded processor";
5659ee7876kaiw	case EM_ARC_A5: return "ARC Cores Tangent-A5";
5669ee7876kaiw	case EM_XTENSA: return "Tensilica Xtensa Architecture";
5679ee7876kaiw	case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
5689ee7876kaiw	case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
5699ee7876kaiw	case EM_NS32K: return "National Semiconductor 32000 series";
5709ee7876kaiw	case EM_TPC: return "Tenor Network TPC processor";
5719ee7876kaiw	case EM_SNP1K: return "Trebia SNP 1000 processor";
5729ee7876kaiw	case EM_ST200: return "STMicroelectronics ST200 microcontroller";
5739ee7876kaiw	case EM_IP2K: return "Ubicom IP2xxx microcontroller family";
5749ee7876kaiw	case EM_MAX: return "MAX Processor";
5759ee7876kaiw	case EM_CR: return "National Semiconductor CompactRISC microprocessor";
5769ee7876kaiw	case EM_F2MC16: return "Fujitsu F2MC16";
5779ee7876kaiw	case EM_MSP430: return "TI embedded microcontroller msp430";
5789ee7876kaiw	case EM_BLACKFIN: return "Analog Devices Blackfin (DSP) processor";
5799ee7876kaiw	case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
5809ee7876kaiw	case EM_SEP: return "Sharp embedded microprocessor";
5819ee7876kaiw	case EM_ARCA: return "Arca RISC Microprocessor";
5829ee7876kaiw	case EM_UNICORE: return "Microprocessor series from PKU-Unity Ltd";
583a9e16ddemaste	case EM_AARCH64: return "AArch64";
584faf3fc6emaste	case EM_RISCV: return "RISC-V";
5859ee7876kaiw	default:
5869ee7876kaiw		snprintf(s_mach, sizeof(s_mach), "<unknown: %#x>", mach);
5879ee7876kaiw		return (s_mach);
5889ee7876kaiw	}
5899ee7876kaiw
5909ee7876kaiw}
5919ee7876kaiw
5929ee7876kaiwstatic const char *
5939ee7876kaiwelf_class(unsigned int class)
5949ee7876kaiw{
5959ee7876kaiw	static char s_class[32];
5969ee7876kaiw
5979ee7876kaiw	switch (class) {
5989ee7876kaiw	case ELFCLASSNONE: return "none";
5999ee7876kaiw	case ELFCLASS32: return "ELF32";
6009ee7876kaiw	case ELFCLASS64: return "ELF64";
6019ee7876kaiw	default:
6029ee7876kaiw		snprintf(s_class, sizeof(s_class), "<unknown: %#x>", class);
6039ee7876kaiw		return (s_class);
6049ee7876kaiw	}
6059ee7876kaiw}
6069ee7876kaiw
6079ee7876kaiwstatic const char *
6089ee7876kaiwelf_endian(unsigned int endian)
6099ee7876kaiw{
6109ee7876kaiw	static char s_endian[32];
6119ee7876kaiw
6129ee7876kaiw	switch (endian) {
6139ee7876kaiw	case ELFDATANONE: return "none";
6149ee7876kaiw	case ELFDATA2LSB: return "2's complement, little endian";
6159ee7876kaiw	case ELFDATA2MSB: return "2's complement, big endian";
6169ee7876kaiw	default:
6179ee7876kaiw		snprintf(s_endian, sizeof(s_endian), "<unknown: %#x>", endian);
6189ee7876kaiw		return (s_endian);
6199ee7876kaiw	}
6209ee7876kaiw}
6219ee7876kaiw
6229ee7876kaiwstatic const char *
6239ee7876kaiwelf_type(unsigned int type)
6249ee7876kaiw{
6259ee7876kaiw	static char s_type[32];
6269ee7876kaiw
6279ee7876kaiw	switch (type) {
6289ee7876kaiw	case ET_NONE: return "NONE (None)";
6299ee7876kaiw	case ET_REL: return "REL (Relocatable file)";
6309ee7876kaiw	case ET_EXEC: return "EXEC (Executable file)";
6319ee7876kaiw	case ET_DYN: return "DYN (Shared object file)";
6329ee7876kaiw	case ET_CORE: return "CORE (Core file)";
6339ee7876kaiw	default:
6349ee7876kaiw		if (type >= ET_LOPROC)
6359ee7876kaiw			snprintf(s_type, sizeof(s_type), "<proc: %#x>", type);
6369ee7876kaiw		else if (type >= ET_LOOS && type <= ET_HIOS)
6379ee7876kaiw			snprintf(s_type, sizeof(s_type), "<os: %#x>", type);
6389ee7876kaiw		else
6399ee7876kaiw			snprintf(s_type, sizeof(s_type), "<unknown: %#x>",
6409ee7876kaiw			    type);
6419ee7876kaiw		return (s_type);
6429ee7876kaiw	}
6439ee7876kaiw}
6449ee7876kaiw
6459ee7876kaiwstatic const char *
6469ee7876kaiwelf_ver(unsigned int ver)
6479ee7876kaiw{
6489ee7876kaiw	static char s_ver[32];
6499ee7876kaiw
6509ee7876kaiw	switch (ver) {
6519ee7876kaiw	case EV_CURRENT: return "(current)";
6529ee7876kaiw	case EV_NONE: return "(none)";
6539ee7876kaiw	default:
6549ee7876kaiw		snprintf(s_ver, sizeof(s_ver), "<unknown: %#x>",
6559ee7876kaiw		    ver);
6569ee7876kaiw		return (s_ver);
6579ee7876kaiw	}
6589ee7876kaiw}
6599ee7876kaiw
6609ee7876kaiwstatic const char *
661d9111a9emastephdr_type(unsigned int mach, unsigned int ptype)
6629ee7876kaiw{
6639ee7876kaiw	static char s_ptype[32];
6649ee7876kaiw
665d9111a9emaste	if (ptype >= PT_LOPROC && ptype <= PT_HIPROC) {
666d9111a9emaste		switch (mach) {
667d9111a9emaste		case EM_ARM:
668d9111a9emaste			switch (ptype) {
669d9111a9emaste			case PT_ARM_ARCHEXT: return "ARM_ARCHEXT";
670d9111a9emaste			case PT_ARM_EXIDX: return "ARM_EXIDX";
671d9111a9emaste			}
672d9111a9emaste			break;
673d9111a9emaste		}
674d9111a9emaste		snprintf(s_ptype, sizeof(s_ptype), "LOPROC+%#x",
675d9111a9emaste		    ptype - PT_LOPROC);
676d9111a9emaste		return (s_ptype);
677d9111a9emaste	}
678d9111a9emaste
6799ee7876kaiw	switch (ptype) {
6809ee7876kaiw	case PT_NULL: return "NULL";
6819ee7876kaiw	case PT_LOAD: return "LOAD";
6829ee7876kaiw	case PT_DYNAMIC: return "DYNAMIC";
6839ee7876kaiw	case PT_INTERP: return "INTERP";
6849ee7876kaiw	case PT_NOTE: return "NOTE";
6859ee7876kaiw	case PT_SHLIB: return "SHLIB";
6869ee7876kaiw	case PT_PHDR: return "PHDR";
6879ee7876kaiw	case PT_TLS: return "TLS";
6889ee7876kaiw	case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
6899ee7876kaiw	case PT_GNU_STACK: return "GNU_STACK";
6909ee7876kaiw	case PT_GNU_RELRO: return "GNU_RELRO";
6911cb7944csjp	case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
6921cb7944csjp	case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
6931cb7944csjp	case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
6949ee7876kaiw	default:
695d9111a9emaste		if (ptype >= PT_LOOS && ptype <= PT_HIOS)
6969ee7876kaiw			snprintf(s_ptype, sizeof(s_ptype), "LOOS+%#x",
6979ee7876kaiw			    ptype - PT_LOOS);
6989ee7876kaiw		else
6999ee7876kaiw			snprintf(s_ptype, sizeof(s_ptype), "<unknown: %#x>",
7009ee7876kaiw			    ptype);
7019ee7876kaiw		return (s_ptype);
7029ee7876kaiw	}
7039ee7876kaiw}
7049ee7876kaiw
7059ee7876kaiwstatic const char *
7069ee7876kaiwsection_type(unsigned int mach, unsigned int stype)
7079ee7876kaiw{
7089ee7876kaiw	static char s_stype[32];
7099ee7876kaiw
7109ee7876kaiw	if (stype >= SHT_LOPROC && stype <= SHT_HIPROC) {
7119ee7876kaiw		switch (mach) {
712d9111a9emaste		case EM_ARM:
713d9111a9emaste			switch (stype) {
714d9111a9emaste			case SHT_ARM_EXIDX: return "ARM_EXIDX";
715d9111a9emaste			case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
716d9111a9emaste			case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
717d9111a9emaste			case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
718d9111a9emaste			case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
719d9111a9emaste			}
720d9111a9emaste			break;
7219ee7876kaiw		case EM_X86_64:
7229ee7876kaiw			switch (stype) {
723db27a04emaste			case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
7249ee7876kaiw			default:
7259ee7876kaiw				break;
7269ee7876kaiw			}
7279ee7876kaiw			break;
7289ee7876kaiw		case EM_MIPS:
7299ee7876kaiw		case EM_MIPS_RS3_LE:
7309ee7876kaiw			switch (stype) {
7319ee7876kaiw			case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
7329ee7876kaiw			case SHT_MIPS_MSYM: return "MIPS_MSYM";
7339ee7876kaiw			case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
7349ee7876kaiw			case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
7359ee7876kaiw			case SHT_MIPS_UCODE: return "MIPS_UCODE";
7369ee7876kaiw			case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
7379ee7876kaiw			case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
7389ee7876kaiw			case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
7399ee7876kaiw			case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
7409ee7876kaiw			case SHT_MIPS_RELD: return "MIPS_RELD";
7419ee7876kaiw			case SHT_MIPS_IFACE: return "MIPS_IFACE";
7429ee7876kaiw			case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
7439ee7876kaiw			case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
7449ee7876kaiw			case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
7459ee7876kaiw			case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
7469ee7876kaiw			case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
7479ee7876kaiw			case SHT_MIPS_DWARF: return "MIPS_DWARF";
7489ee7876kaiw			case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
7499ee7876kaiw			case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
7509ee7876kaiw			case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
7519ee7876kaiw			case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
7529ee7876kaiw			case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
7539ee7876kaiw			case SHT_MIPS_XLATE: return "MIPS_XLATE";
7549ee7876kaiw			case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
7559ee7876kaiw			case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
7569ee7876kaiw			case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
7579ee7876kaiw			case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
7589ee7876kaiw			case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
759c90b1e5emaste			case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
7609ee7876kaiw			default:
7619ee7876kaiw				break;
7629ee7876kaiw			}
7639ee7876kaiw			break;
7649ee7876kaiw		default:
7659ee7876kaiw			break;
7669ee7876kaiw		}
7679ee7876kaiw
7689ee7876kaiw		snprintf(s_stype, sizeof(s_stype), "LOPROC+%#x",
7699ee7876kaiw		    stype - SHT_LOPROC);
7709ee7876kaiw		return (s_stype);
7719ee7876kaiw	}
7729ee7876kaiw
7739ee7876kaiw	switch (stype) {
7749ee7876kaiw	case SHT_NULL: return "NULL";
7759ee7876kaiw	case SHT_PROGBITS: return "PROGBITS";
7769ee7876kaiw	case SHT_SYMTAB: return "SYMTAB";
7779ee7876kaiw	case SHT_STRTAB: return "STRTAB";
7789ee7876kaiw	case SHT_RELA: return "RELA";
7799ee7876kaiw	case SHT_HASH: return "HASH";
7809ee7876kaiw	case SHT_DYNAMIC: return "DYNAMIC";
7819ee7876kaiw	case SHT_NOTE: return "NOTE";
7829ee7876kaiw	case SHT_NOBITS: return "NOBITS";
7839ee7876kaiw	case SHT_REL: return "REL";
7849ee7876kaiw	case SHT_SHLIB: return "SHLIB";
7859ee7876kaiw	case SHT_DYNSYM: return "DYNSYM";
7869ee7876kaiw	case SHT_INIT_ARRAY: return "INIT_ARRAY";
7879ee7876kaiw	case SHT_FINI_ARRAY: return "FINI_ARRAY";
7889ee7876kaiw	case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
7899ee7876kaiw	case SHT_GROUP: return "GROUP";
7909ee7876kaiw	case SHT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
7919ee7876kaiw	case SHT_SUNW_dof: return "SUNW_dof";
7929ee7876kaiw	case SHT_SUNW_cap: return "SUNW_cap";
7939ee7876kaiw	case SHT_GNU_HASH: return "GNU_HASH";
7949ee7876kaiw	case SHT_SUNW_ANNOTATE: return "SUNW_ANNOTATE";
7959ee7876kaiw	case SHT_SUNW_DEBUGSTR: return "SUNW_DEBUGSTR";
7969ee7876kaiw	case SHT_SUNW_DEBUG: return "SUNW_DEBUG";
7979ee7876kaiw	case SHT_SUNW_move: return "SUNW_move";
7989ee7876kaiw	case SHT_SUNW_COMDAT: return "SUNW_COMDAT";
7999ee7876kaiw	case SHT_SUNW_syminfo: return "SUNW_syminfo";
8009ee7876kaiw	case SHT_SUNW_verdef: return "SUNW_verdef";
8019ee7876kaiw	case SHT_SUNW_verneed: return "SUNW_verneed";
8029ee7876kaiw	case SHT_SUNW_versym: return "SUNW_versym";
8039ee7876kaiw	default:
8049ee7876kaiw		if (stype >= SHT_LOOS && stype <= SHT_HIOS)
8059ee7876kaiw			snprintf(s_stype, sizeof(s_stype), "LOOS+%#x",
8069ee7876kaiw			    stype - SHT_LOOS);
8079ee7876kaiw		else if (stype >= SHT_LOUSER)
8089ee7876kaiw			snprintf(s_stype, sizeof(s_stype), "LOUSER+%#x",
8099ee7876kaiw			    stype - SHT_LOUSER);
8109ee7876kaiw		else
8119ee7876kaiw			snprintf(s_stype, sizeof(s_stype), "<unknown: %#x>",
8129ee7876kaiw			    stype);
8139ee7876kaiw		return (s_stype);
8149ee7876kaiw	}
8159ee7876kaiw}
8169ee7876kaiw
8179ee7876kaiwstatic const char *
8189ee7876kaiwdt_type(unsigned int mach, unsigned int dtype)
8199ee7876kaiw{
8209ee7876kaiw	static char s_dtype[32];
8219ee7876kaiw
822506c650emaste	switch (dtype) {
823506c650emaste	case DT_NULL: return "NULL";
824506c650emaste	case DT_NEEDED: return "NEEDED";
825506c650emaste	case DT_PLTRELSZ: return "PLTRELSZ";
826506c650emaste	case DT_PLTGOT: return "PLTGOT";
827506c650emaste	case DT_HASH: return "HASH";
828506c650emaste	case DT_STRTAB: return "STRTAB";
829506c650emaste	case DT_SYMTAB: return "SYMTAB";
830506c650emaste	case DT_RELA: return "RELA";
831506c650emaste	case DT_RELASZ: return "RELASZ";
832506c650emaste	case DT_RELAENT: return "RELAENT";
833506c650emaste	case DT_STRSZ: return "STRSZ";
834506c650emaste	case DT_SYMENT: return "SYMENT";
835506c650emaste	case DT_INIT: return "INIT";
836506c650emaste	case DT_FINI: return "FINI";
837506c650emaste	case DT_SONAME: return "SONAME";
838506c650emaste	case DT_RPATH: return "RPATH";
839506c650emaste	case DT_SYMBOLIC: return "SYMBOLIC";
840506c650emaste	case DT_REL: return "REL";
841506c650emaste	case DT_RELSZ: return "RELSZ";
842506c650emaste	case DT_RELENT: return "RELENT";
843506c650emaste	case DT_PLTREL: return "PLTREL";
844506c650emaste	case DT_DEBUG: return "DEBUG";
845506c650emaste	case DT_TEXTREL: return "TEXTREL";
846506c650emaste	case DT_JMPREL: return "JMPREL";
847506c650emaste	case DT_BIND_NOW: return "BIND_NOW";
848506c650emaste	case DT_INIT_ARRAY: return "INIT_ARRAY";
849506c650emaste	case DT_FINI_ARRAY: return "FINI_ARRAY";
850506c650emaste	case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
851506c650emaste	case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
852506c650emaste	case DT_RUNPATH: return "RUNPATH";
853506c650emaste	case DT_FLAGS: return "FLAGS";
854506c650emaste	case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
855506c650emaste	case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
856506c650emaste	case DT_MAXPOSTAGS: return "MAXPOSTAGS";
857506c650emaste	case DT_SUNW_AUXILIARY: return "SUNW_AUXILIARY";
858506c650emaste	case DT_SUNW_RTLDINF: return "SUNW_RTLDINF";
859506c650emaste	case DT_SUNW_FILTER: return "SUNW_FILTER";
860506c650emaste	case DT_SUNW_CAP: return "SUNW_CAP";
861994b0b9emaste	case DT_SUNW_ASLR: return "SUNW_ASLR";
862506c650emaste	case DT_CHECKSUM: return "CHECKSUM";
863506c650emaste	case DT_PLTPADSZ: return "PLTPADSZ";
864506c650emaste	case DT_MOVEENT: return "MOVEENT";
865506c650emaste	case DT_MOVESZ: return "MOVESZ";
866506c650emaste	case DT_FEATURE: return "FEATURE";
867506c650emaste	case DT_POSFLAG_1: return "POSFLAG_1";
868506c650emaste	case DT_SYMINSZ: return "SYMINSZ";
869506c650emaste	case DT_SYMINENT: return "SYMINENT";
870506c650emaste	case DT_GNU_HASH: return "GNU_HASH";
871506c650emaste	case DT_TLSDESC_PLT: return "DT_TLSDESC_PLT";
872506c650emaste	case DT_TLSDESC_GOT: return "DT_TLSDESC_GOT";
873506c650emaste	case DT_GNU_CONFLICT: return "GNU_CONFLICT";
874506c650emaste	case DT_GNU_LIBLIST: return "GNU_LIBLIST";
875506c650emaste	case DT_CONFIG: return "CONFIG";
876506c650emaste	case DT_DEPAUDIT: return "DEPAUDIT";
877506c650emaste	case DT_AUDIT: return "AUDIT";
878506c650emaste	case DT_PLTPAD: return "PLTPAD";
879506c650emaste	case DT_MOVETAB: return "MOVETAB";
880506c650emaste	case DT_SYMINFO: return "SYMINFO";
881506c650emaste	case DT_VERSYM: return "VERSYM";
882506c650emaste	case DT_RELACOUNT: return "RELACOUNT";
883506c650emaste	case DT_RELCOUNT: return "RELCOUNT";
884506c650emaste	case DT_FLAGS_1: return "FLAGS_1";
885506c650emaste	case DT_VERDEF: return "VERDEF";
886506c650emaste	case DT_VERDEFNUM: return "VERDEFNUM";
887506c650emaste	case DT_VERNEED: return "VERNEED";
888506c650emaste	case DT_VERNEEDNUM: return "VERNEEDNUM";
889506c650emaste	case DT_AUXILIARY: return "AUXILIARY";
890506c650emaste	case DT_USED: return "USED";
891506c650emaste	case DT_FILTER: return "FILTER";
892506c650emaste	case DT_GNU_PRELINKED: return "GNU_PRELINKED";
893506c650emaste	case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
894506c650emaste	case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
895506c650emaste	}
896506c650emaste
8979ee7876kaiw	if (dtype >= DT_LOPROC && dtype <= DT_HIPROC) {
8989ee7876kaiw		switch (mach) {
8999ee7876kaiw		case EM_ARM:
9009ee7876kaiw			switch (dtype) {
9019ee7876kaiw			case DT_ARM_SYMTABSZ:
9029ee7876kaiw				return "ARM_SYMTABSZ";
9039ee7876kaiw			default:
9049ee7876kaiw				break;
9059ee7876kaiw			}
9069ee7876kaiw			break;
9079ee7876kaiw		case EM_MIPS:
9089ee7876kaiw		case EM_MIPS_RS3_LE:
9099ee7876kaiw			switch (dtype) {
9109ee7876kaiw			case DT_MIPS_RLD_VERSION:
9119ee7876kaiw				return "MIPS_RLD_VERSION";
9129ee7876kaiw			case DT_MIPS_TIME_STAMP:
9139ee7876kaiw				return "MIPS_TIME_STAMP";
9149ee7876kaiw			case DT_MIPS_ICHECKSUM:
9159ee7876kaiw				return "MIPS_ICHECKSUM";
9169ee7876kaiw			case DT_MIPS_IVERSION:
9179ee7876kaiw				return "MIPS_IVERSION";
9189ee7876kaiw			case DT_MIPS_FLAGS:
9199ee7876kaiw				return "MIPS_FLAGS";
9209ee7876kaiw			case DT_MIPS_BASE_ADDRESS:
9219ee7876kaiw				return "MIPS_BASE_ADDRESS";
9229ee7876kaiw			case DT_MIPS_CONFLICT:
9239ee7876kaiw				return "MIPS_CONFLICT";
9249ee7876kaiw			case DT_MIPS_LIBLIST:
9259ee7876kaiw				return "MIPS_LIBLIST";
9269ee7876kaiw			case DT_MIPS_LOCAL_GOTNO:
9279ee7876kaiw				return "MIPS_LOCAL_GOTNO";
9289ee7876kaiw			case DT_MIPS_CONFLICTNO:
9299ee7876kaiw				return "MIPS_CONFLICTNO";
9309ee7876kaiw			case DT_MIPS_LIBLISTNO:
9319ee7876kaiw				return "MIPS_LIBLISTNO";
9329ee7876kaiw			case DT_MIPS_SYMTABNO:
9339ee7876kaiw				return "MIPS_SYMTABNO";
9349ee7876kaiw			case DT_MIPS_UNREFEXTNO:
9359ee7876kaiw				return "MIPS_UNREFEXTNO";
9369ee7876kaiw			case DT_MIPS_GOTSYM:
9379ee7876kaiw				return "MIPS_GOTSYM";
9389ee7876kaiw			case DT_MIPS_HIPAGENO:
9399ee7876kaiw				return "MIPS_HIPAGENO";
9409ee7876kaiw			case DT_MIPS_RLD_MAP:
9419ee7876kaiw				return "MIPS_RLD_MAP";
9429ee7876kaiw			case DT_MIPS_DELTA_CLASS:
9439ee7876kaiw				return "MIPS_DELTA_CLASS";
9449ee7876kaiw			case DT_MIPS_DELTA_CLASS_NO:
9459ee7876kaiw				return "MIPS_DELTA_CLASS_NO";
9469ee7876kaiw			case DT_MIPS_DELTA_INSTANCE:
9479ee7876kaiw				return "MIPS_DELTA_INSTANCE";
9489ee7876kaiw			case DT_MIPS_DELTA_INSTANCE_NO:
9499ee7876kaiw				return "MIPS_DELTA_INSTANCE_NO";
9509ee7876kaiw			case DT_MIPS_DELTA_RELOC:
9519ee7876kaiw				return "MIPS_DELTA_RELOC";
9529ee7876kaiw			case DT_MIPS_DELTA_RELOC_NO:
9539ee7876kaiw				return "MIPS_DELTA_RELOC_NO";
9549ee7876kaiw			case DT_MIPS_DELTA_SYM:
9559ee7876kaiw				return "MIPS_DELTA_SYM";
9569ee7876kaiw			case DT_MIPS_DELTA_SYM_NO:
9579ee7876kaiw				return "MIPS_DELTA_SYM_NO";
9589ee7876kaiw			case DT_MIPS_DELTA_CLASSSYM:
9599ee7876kaiw				return "MIPS_DELTA_CLASSSYM";
9609ee7876kaiw			case DT_MIPS_DELTA_CLASSSYM_NO:
9619ee7876kaiw				return "MIPS_DELTA_CLASSSYM_NO";
9629ee7876kaiw			case DT_MIPS_CXX_FLAGS:
9639ee7876kaiw				return "MIPS_CXX_FLAGS";
9649ee7876kaiw			case DT_MIPS_PIXIE_INIT:
9659ee7876kaiw				return "MIPS_PIXIE_INIT";
9669ee7876kaiw			case DT_MIPS_SYMBOL_LIB:
9679ee7876kaiw				return "MIPS_SYMBOL_LIB";
9689ee7876kaiw			case DT_MIPS_LOCALPAGE_GOTIDX:
9699ee7876kaiw				return "MIPS_LOCALPAGE_GOTIDX";
9709ee7876kaiw			case DT_MIPS_LOCAL_GOTIDX:
9719ee7876kaiw				return "MIPS_LOCAL_GOTIDX";
9729ee7876kaiw			case DT_MIPS_HIDDEN_GOTIDX:
9739ee7876kaiw				return "MIPS_HIDDEN_GOTIDX";
9749ee7876kaiw			case DT_MIPS_PROTECTED_GOTIDX:
9759ee7876kaiw				return "MIPS_PROTECTED_GOTIDX";
9769ee7876kaiw			case DT_MIPS_OPTIONS:
9779ee7876kaiw				return "MIPS_OPTIONS";
9789ee7876kaiw			case DT_MIPS_INTERFACE:
9799ee7876kaiw				return "MIPS_INTERFACE";
9809ee7876kaiw			case DT_MIPS_DYNSTR_ALIGN:
9819ee7876kaiw				return "MIPS_DYNSTR_ALIGN";
9829ee7876kaiw			case DT_MIPS_INTERFACE_SIZE:
9839ee7876kaiw				return "MIPS_INTERFACE_SIZE";
9849ee7876kaiw			case DT_MIPS_RLD_TEXT_RESOLVE_ADDR:
9859ee7876kaiw				return "MIPS_RLD_TEXT_RESOLVE_ADDR";
9869ee7876kaiw			case DT_MIPS_PERF_SUFFIX:
9879ee7876kaiw				return "MIPS_PERF_SUFFIX";
9889ee7876kaiw			case DT_MIPS_COMPACT_SIZE:
9899ee7876kaiw				return "MIPS_COMPACT_SIZE";
9909ee7876kaiw			case DT_MIPS_GP_VALUE:
9919ee7876kaiw				return "MIPS_GP_VALUE";
9929ee7876kaiw			case DT_MIPS_AUX_DYNAMIC:
9939ee7876kaiw				return "MIPS_AUX_DYNAMIC";
9949ee7876kaiw			case DT_MIPS_PLTGOT:
9959ee7876kaiw				return "MIPS_PLTGOT";
9969ee7876kaiw			case DT_MIPS_RLD_OBJ_UPDATE:
9979ee7876kaiw				return "MIPS_RLD_OBJ_UPDATE";
9989ee7876kaiw			case DT_MIPS_RWPLT:
9999ee7876kaiw				return "MIPS_RWPLT";
10009ee7876kaiw			default:
10019ee7876kaiw				break;
10029ee7876kaiw			}
10039ee7876kaiw			break;
10049ee7876kaiw		case EM_SPARC:
10059ee7876kaiw		case EM_SPARC32PLUS:
10069ee7876kaiw		case EM_SPARCV9:
10079ee7876kaiw			switch (dtype) {
10089ee7876kaiw			case DT_SPARC_REGISTER:
10099ee7876kaiw				return "DT_SPARC_REGISTER";
10109ee7876kaiw			default:
10119ee7876kaiw				break;
10129ee7876kaiw			}
10139ee7876kaiw			break;
10149ee7876kaiw		default:
10159ee7876kaiw			break;
10169ee7876kaiw		}
10179ee7876kaiw	}
10189ee7876kaiw
1019506c650emaste	snprintf(s_dtype, sizeof(s_dtype), "<unknown: %#x>", dtype);
1020506c650emaste	return (s_dtype);
10219ee7876kaiw}
10229ee7876kaiw
10239ee7876kaiwstatic const char *
10249ee7876kaiwst_bind(unsigned int sbind)
10259ee7876kaiw{
10269ee7876kaiw	static char s_sbind[32];
10279ee7876kaiw
10289ee7876kaiw	switch (sbind) {
10299ee7876kaiw	case STB_LOCAL: return "LOCAL";
10309ee7876kaiw	case STB_GLOBAL: return "GLOBAL";
10319ee7876kaiw	case STB_WEAK: return "WEAK";
103285217deemaste	case STB_GNU_UNIQUE: return "UNIQUE";
10339ee7876kaiw	default:
10349ee7876kaiw		if (sbind >= STB_LOOS && sbind <= STB_HIOS)
10359ee7876kaiw			return "OS";
10369ee7876kaiw		else if (sbind >= STB_LOPROC && sbind <= STB_HIPROC)
10379ee7876kaiw			return "PROC";
10389ee7876kaiw		else
10399ee7876kaiw			snprintf(s_sbind, sizeof(s_sbind), "<unknown: %#x>",
10409ee7876kaiw			    sbind);
10419ee7876kaiw		return (s_sbind);
10429ee7876kaiw	}
10439ee7876kaiw}
10449ee7876kaiw
10459ee7876kaiwstatic const char *
1046db27a04emastest_type(unsigned int mach, unsigned int os, unsigned int stype)
10479ee7876kaiw{
10489ee7876kaiw	static char s_stype[32];
10499ee7876kaiw
10509ee7876kaiw	switch (stype) {
10519ee7876kaiw	case STT_NOTYPE: return "NOTYPE";
10529ee7876kaiw	case STT_OBJECT: return "OBJECT";
10539ee7876kaiw	case STT_FUNC: return "FUNC";
10549ee7876kaiw	case STT_SECTION: return "SECTION";
10559ee7876kaiw	case STT_FILE: return "FILE";
10569ee7876kaiw	case STT_COMMON: return "COMMON";
10579ee7876kaiw	case STT_TLS: return "TLS";
10589ee7876kaiw	default:
1059db27a04emaste		if (stype >= STT_LOOS && stype <= STT_HIOS) {
1060db27a04emaste			if ((os == ELFOSABI_GNU || os == ELFOSABI_FREEBSD) &&
1061db27a04emaste			    stype == STT_GNU_IFUNC)
1062db27a04emaste				return "IFUNC";
10639ee7876kaiw			snprintf(s_stype, sizeof(s_stype), "OS+%#x",
10649ee7876kaiw			    stype - STT_LOOS);
1065db27a04emaste		} else if (stype >= STT_LOPROC && stype <= STT_HIPROC) {
106685217deemaste			if (mach == EM_SPARCV9 && stype == STT_SPARC_REGISTER)
106785217deemaste				return "REGISTER";
10689ee7876kaiw			snprintf(s_stype, sizeof(s_stype), "PROC+%#x",
10699ee7876kaiw			    stype - STT_LOPROC);
107085217deemaste		} else
10719ee7876kaiw			snprintf(s_stype, sizeof(s_stype), "<unknown: %#x>",
10729ee7876kaiw			    stype);
10739ee7876kaiw		return (s_stype);
10749ee7876kaiw	}
10759ee7876kaiw}
10769ee7876kaiw
10779ee7876kaiwstatic const char *
10789ee7876kaiwst_vis(unsigned int svis)
10799ee7876kaiw{
10809ee7876kaiw	static char s_svis[32];
10819ee7876kaiw
10829ee7876kaiw	switch(svis) {
10839ee7876kaiw	case STV_DEFAULT: return "DEFAULT";
10849ee7876kaiw	case STV_INTERNAL: return "INTERNAL";
10859ee7876kaiw	case STV_HIDDEN: return "HIDDEN";
10869ee7876kaiw	case STV_PROTECTED: return "PROTECTED";
10879ee7876kaiw	default:
10889ee7876kaiw		snprintf(s_svis, sizeof(s_svis), "<unknown: %#x>", svis);
10899ee7876kaiw		return (s_svis);
10909ee7876kaiw	}
10919ee7876kaiw}
10929ee7876kaiw
10939ee7876kaiwstatic const char *
10949ee7876kaiwst_shndx(unsigned int shndx)
10959ee7876kaiw{
10969ee7876kaiw	static char s_shndx[32];
10979ee7876kaiw
10989ee7876kaiw	switch (shndx) {
10999ee7876kaiw	case SHN_UNDEF: return "UND";
11009ee7876kaiw	case SHN_ABS: return "ABS";
11019ee7876kaiw	case SHN_COMMON: return "COM";
11029ee7876kaiw	default:
11039ee7876kaiw		if (shndx >= SHN_LOPROC && shndx <= SHN_HIPROC)
11049ee7876kaiw			return "PRC";
11059ee7876kaiw		else if (shndx >= SHN_LOOS && shndx <= SHN_HIOS)
11069ee7876kaiw			return "OS";
11079ee7876kaiw		else
11089ee7876kaiw			snprintf(s_shndx, sizeof(s_shndx), "%u", shndx);
11099ee7876kaiw		return (s_shndx);
11109ee7876kaiw	}
11119ee7876kaiw}
11129ee7876kaiw
11139ee7876kaiwstatic struct {
11149ee7876kaiw	const char *ln;
11159ee7876kaiw	char sn;
11169ee7876kaiw	int value;
11179ee7876kaiw} section_flag[] = {
11189ee7876kaiw	{"WRITE", 'W', SHF_WRITE},
11199ee7876kaiw	{"ALLOC", 'A', SHF_ALLOC},
11209ee7876kaiw	{"EXEC", 'X', SHF_EXECINSTR},
11219ee7876kaiw	{"MERGE", 'M', SHF_MERGE},
11229ee7876kaiw	{"STRINGS", 'S', SHF_STRINGS},
11239ee7876kaiw	{"INFO LINK", 'I', SHF_INFO_LINK},
11249ee7876kaiw	{"OS NONCONF", 'O', SHF_OS_NONCONFORMING},
11259ee7876kaiw	{"GROUP", 'G', SHF_GROUP},
11269ee7876kaiw	{"TLS", 'T', SHF_TLS},
1127db27a04emaste	{"COMPRESSED", 'C', SHF_COMPRESSED},
11289ee7876kaiw	{NULL, 0, 0}
11299ee7876kaiw};
11309ee7876kaiw
11319ee7876kaiwstatic const char *
1132e016e1femastenote_type(const char *name, unsigned int et, unsigned int nt)
11339ee7876kaiw{
1134a86377aemaste	if ((strcmp(name, "CORE") == 0 || strcmp(name, "LINUX") == 0) &&
1135a86377aemaste	    et == ET_CORE)
1136e016e1femaste		return note_type_linux_core(nt);
1137e016e1femaste	else if (strcmp(name, "FreeBSD") == 0)
1138e016e1femaste		if (et == ET_CORE)
1139e016e1femaste			return note_type_freebsd_core(nt);
1140e016e1femaste		else
1141e016e1femaste			return note_type_freebsd(nt);
1142e016e1femaste	else if (strcmp(name, "GNU") == 0 && et != ET_CORE)
1143e016e1femaste		return note_type_gnu(nt);
1144e016e1femaste	else if (strcmp(name, "NetBSD") == 0 && et != ET_CORE)
1145e016e1femaste		return note_type_netbsd(nt);
1146e016e1femaste	else if (strcmp(name, "OpenBSD") == 0 && et != ET_CORE)
1147e016e1femaste		return note_type_openbsd(nt);
11487e478f4emaste	else if (strcmp(name, "Xen") == 0 && et != ET_CORE)
11497e478f4emaste		return note_type_xen(nt);
1150e016e1femaste	return note_type_unknown(nt);
1151e016e1femaste}
11529ee7876kaiw
1153e016e1femastestatic const char *
1154e016e1femastenote_type_freebsd(unsigned int nt)
1155e016e1femaste{
1156e016e1femaste	switch (nt) {
1157e016e1femaste	case 1: return "NT_FREEBSD_ABI_TAG";
1158e016e1femaste	case 2: return "NT_FREEBSD_NOINIT_TAG";
1159e016e1femaste	case 3: return "NT_FREEBSD_ARCH_TAG";
11606957cb7emaste	case 4: return "NT_FREEBSD_FEATURE_CTL";
1161e016e1femaste	default: return (note_type_unknown(nt));
1162e016e1femaste	}
1163e016e1femaste}
1164e016e1femaste
1165e016e1femastestatic const char *
1166e016e1femastenote_type_freebsd_core(unsigned int nt)
1167e016e1femaste{
1168e016e1femaste	switch (nt) {
1169e016e1femaste	case 1: return "NT_PRSTATUS";
1170e016e1femaste	case 2: return "NT_FPREGSET";
1171e016e1femaste	case 3: return "NT_PRPSINFO";
1172e016e1femaste	case 7: return "NT_THRMISC";
1173e016e1femaste	case 8: return "NT_PROCSTAT_PROC";
1174e016e1femaste	case 9: return "NT_PROCSTAT_FILES";
1175e016e1femaste	case 10: return "NT_PROCSTAT_VMMAP";
1176e016e1femaste	case 11: return "NT_PROCSTAT_GROUPS";
1177e016e1femaste	case 12: return "NT_PROCSTAT_UMASK";
1178e016e1femaste	case 13: return "NT_PROCSTAT_RLIMIT";
1179e016e1femaste	case 14: return "NT_PROCSTAT_OSREL";
1180e016e1femaste	case 15: return "NT_PROCSTAT_PSSTRINGS";
1181e016e1femaste	case 16: return "NT_PROCSTAT_AUXV";
11826502329jhb	case 17: return "NT_PTLWPINFO";
1183ec4371djhibbits	case 0x100: return "NT_PPC_VMX (ppc Altivec registers)";
1184ec4371djhibbits	case 0x102: return "NT_PPC_VSX (ppc VSX registers)";
1185e016e1femaste	case 0x202: return "NT_X86_XSTATE (x86 XSAVE extended state)";
11866502329jhb	case 0x400: return "NT_ARM_VFP (arm VFP registers)";
1187e016e1femaste	default: return (note_type_unknown(nt));
1188e016e1femaste	}
1189e016e1femaste}
1190e016e1femaste
1191e016e1femastestatic const char *
1192e016e1femastenote_type_linux_core(unsigned int nt)
1193e016e1femaste{
1194e016e1femaste	switch (nt) {
1195e016e1femaste	case 1: return "NT_PRSTATUS (Process status)";
1196e016e1femaste	case 2: return "NT_FPREGSET (Floating point information)";
1197e016e1femaste	case 3: return "NT_PRPSINFO (Process information)";
1198a86377aemaste	case 4: return "NT_TASKSTRUCT (Task structure)";
1199e016e1femaste	case 6: return "NT_AUXV (Auxiliary vector)";
1200e016e1femaste	case 10: return "NT_PSTATUS (Linux process status)";
1201e016e1femaste	case 12: return "NT_FPREGS (Linux floating point regset)";
1202e016e1femaste	case 13: return "NT_PSINFO (Linux process information)";
1203e016e1femaste	case 16: return "NT_LWPSTATUS (Linux lwpstatus_t type)";
1204e016e1femaste	case 17: return "NT_LWPSINFO (Linux lwpinfo_t type)";
1205a86377aemaste	case 18: return "NT_WIN32PSTATUS (win32_pstatus structure)";
1206a86377aemaste	case 0x100: return "NT_PPC_VMX (ppc Altivec registers)";
1207a86377aemaste	case 0x102: return "NT_PPC_VSX (ppc VSX registers)";
1208a86377aemaste	case 0x202: return "NT_X86_XSTATE (x86 XSAVE extended state)";
1209a86377aemaste	case 0x300: return "NT_S390_HIGH_GPRS (s390 upper register halves)";
1210a86377aemaste	case 0x301: return "NT_S390_TIMER (s390 timer register)";
1211a86377aemaste	case 0x302: return "NT_S390_TODCMP (s390 TOD comparator register)";
1212a86377aemaste	case 0x303: return "NT_S390_TODPREG (s390 TOD programmable register)";
1213a86377aemaste	case 0x304: return "NT_S390_CTRS (s390 control registers)";
1214a86377aemaste	case 0x305: return "NT_S390_PREFIX (s390 prefix register)";
1215a86377aemaste	case 0x400: return "NT_ARM_VFP (arm VFP registers)";
1216a86377aemaste	case 0x46494c45UL: return "NT_FILE (mapped files)";
1217a86377aemaste	case 0x46E62B7FUL: return "NT_PRXFPREG (Linux user_xfpregs structure)";
1218a86377aemaste	case 0x53494749UL: return "NT_SIGINFO (siginfo_t data)";
1219e016e1femaste	default: return (note_type_unknown(nt));
1220e016e1femaste	}
1221e016e1femaste}
1222e016e1femaste
1223e016e1femastestatic const char *
1224e016e1femastenote_type_gnu(unsigned int nt)
1225e016e1femaste{
1226e016e1femaste	switch (nt) {
1227e016e1femaste	case 1: return "NT_GNU_ABI_TAG";
1228e016e1femaste	case 2: return "NT_GNU_HWCAP (Hardware capabilities)";
1229e016e1femaste	case 3: return "NT_GNU_BUILD_ID (Build id set by ld(1))";
1230e016e1femaste	case 4: return "NT_GNU_GOLD_VERSION (GNU gold version)";
1231ce98938emaste	case 5: return "NT_GNU_PROPERTY_TYPE_0";
1232e016e1femaste	default: return (note_type_unknown(nt));
1233e016e1femaste	}
1234e016e1femaste}
1235e016e1femaste
1236e016e1femastestatic const char *
1237e016e1femastenote_type_netbsd(unsigned int nt)
1238e016e1femaste{
1239e016e1femaste	switch (nt) {
1240e016e1femaste	case 1: return "NT_NETBSD_IDENT";
1241e016e1femaste	default: return (note_type_unknown(nt));
12429ee7876kaiw	}
1243e016e1femaste}
1244e016e1femaste
1245e016e1femastestatic const char *
1246e016e1femastenote_type_openbsd(unsigned int nt)
1247e016e1femaste{
1248e016e1femaste	switch (nt) {
1249e016e1femaste	case 1: return "NT_OPENBSD_IDENT";
1250e016e1femaste	default: return (note_type_unknown(nt));
1251e016e1femaste	}
1252e016e1femaste}
1253e016e1femaste
1254e016e1femastestatic const char *
1255e016e1femastenote_type_unknown(unsigned int nt)
1256e016e1femaste{
1257e016e1femaste	static char s_nt[32];
1258e016e1femaste
1259a86377aemaste	snprintf(s_nt, sizeof(s_nt),
1260a86377aemaste	    nt >= 0x100 ? "<unknown: 0x%x>" : "<unknown: %u>", nt);
1261e016e1femaste	return (s_nt);
12629ee7876kaiw}
12639ee7876kaiw
12647e478f4emastestatic const char *
12657e478f4emastenote_type_xen(unsigned int nt)
12667e478f4emaste{
12677e478f4emaste	switch (nt) {
12687e478f4emaste	case 0: return "XEN_ELFNOTE_INFO";
12697e478f4emaste	case 1: return "XEN_ELFNOTE_ENTRY";
12707e478f4emaste	case 2: return "XEN_ELFNOTE_HYPERCALL_PAGE";
12717e478f4emaste	case 3: return "XEN_ELFNOTE_VIRT_BASE";
12727e478f4emaste	case 4: return "XEN_ELFNOTE_PADDR_OFFSET";
12737e478f4emaste	case 5: return "XEN_ELFNOTE_XEN_VERSION";
12747e478f4emaste	case 6: return "XEN_ELFNOTE_GUEST_OS";
12757e478f4emaste	case 7: return "XEN_ELFNOTE_GUEST_VERSION";
12767e478f4emaste	case 8: return "XEN_ELFNOTE_LOADER";
12777e478f4emaste	case 9: return "XEN_ELFNOTE_PAE_MODE";
12787e478f4emaste	case 10: return "XEN_ELFNOTE_FEATURES";
12797e478f4emaste	case 11: return "XEN_ELFNOTE_BSD_SYMTAB";
12807e478f4emaste	case 12: return "XEN_ELFNOTE_HV_START_LOW";
12817e478f4emaste	case 13: return "XEN_ELFNOTE_L1_MFN_VALID";
12827e478f4emaste	case 14: return "XEN_ELFNOTE_SUSPEND_CANCEL";
12837e478f4emaste	case 15: return "XEN_ELFNOTE_INIT_P2M";
12847e478f4emaste	case 16: return "XEN_ELFNOTE_MOD_START_PFN";
12857e478f4emaste	case 17: return "XEN_ELFNOTE_SUPPORTED_FEATURES";
1286362f185emaste	case 18: return "XEN_ELFNOTE_PHYS32_ENTRY";
12877e478f4emaste	default: return (note_type_unknown(nt));
12887e478f4emaste	}
12897e478f4emaste}
12907e478f4emaste
12919ee7876kaiwstatic struct {
12929ee7876kaiw	const char *name;
12939ee7876kaiw	int value;
12949ee7876kaiw} l_flag[] = {
12959ee7876kaiw	{"EXACT_MATCH", LL_EXACT_MATCH},
12969ee7876kaiw	{"IGNORE_INT_VER", LL_IGNORE_INT_VER},
12979ee7876kaiw	{"REQUIRE_MINOR", LL_REQUIRE_MINOR},
12989ee7876kaiw	{"EXPORTS", LL_EXPORTS},
12999ee7876kaiw	{"DELAY_LOAD", LL_DELAY_LOAD},
13009ee7876kaiw	{"DELTA", LL_DELTA},
13019ee7876kaiw	{NULL, 0}
13029ee7876kaiw};
13039ee7876kaiw
13049ee7876kaiwstatic struct mips_option mips_exceptions_option[] = {
13059ee7876kaiw	{OEX_PAGE0, "PAGE0"},
13069ee7876kaiw	{OEX_SMM, "SMM"},
13079ee7876kaiw	{OEX_PRECISEFP, "PRECISEFP"},
13089ee7876kaiw	{OEX_DISMISS, "DISMISS"},
13099ee7876kaiw	{0, NULL}
13109ee7876kaiw};
13119ee7876kaiw
13129ee7876kaiwstatic struct mips_option mips_pad_option[] = {
13139ee7876kaiw	{OPAD_PREFIX, "PREFIX"},
13149ee7876kaiw	{OPAD_POSTFIX, "POSTFIX"},
13159ee7876kaiw	{OPAD_SYMBOL, "SYMBOL"},
13169ee7876kaiw	{0, NULL}
13179ee7876kaiw};
13189ee7876kaiw
13199ee7876kaiwstatic struct mips_option mips_hwpatch_option[] = {
13209ee7876kaiw	{OHW_R4KEOP, "R4KEOP"},
13219ee7876kaiw	{OHW_R8KPFETCH, "R8KPFETCH"},
13229ee7876kaiw	{OHW_R5KEOP, "R5KEOP"},
13239ee7876kaiw	{OHW_R5KCVTL, "R5KCVTL"},
13249ee7876kaiw	{0, NULL}
13259ee7876kaiw};
13269ee7876kaiw
13279ee7876kaiwstatic struct mips_option mips_hwa_option[] = {
13289ee7876kaiw	{OHWA0_R4KEOP_CHECKED, "R4KEOP_CHECKED"},
13299ee7876kaiw	{OHWA0_R4KEOP_CLEAN, "R4KEOP_CLEAN"},
13309ee7876kaiw	{0, NULL}
13319ee7876kaiw};
13329ee7876kaiw
13339ee7876kaiwstatic struct mips_option mips_hwo_option[] = {
13349ee7876kaiw	{OHWO0_FIXADE, "FIXADE"},
13359ee7876kaiw	{0, NULL}
13369ee7876kaiw};
13379ee7876kaiw
13389ee7876kaiwstatic const char *
13399ee7876kaiwoption_kind(uint8_t kind)
13409ee7876kaiw{
13419ee7876kaiw	static char s_kind[32];
13429ee7876kaiw
13439ee7876kaiw	switch (kind) {
13449ee7876kaiw	case ODK_NULL: return "NULL";
13459ee7876kaiw	case ODK_REGINFO: return "REGINFO";
13469ee7876kaiw	case ODK_EXCEPTIONS: return "EXCEPTIONS";
13479ee7876kaiw	case ODK_PAD: return "PAD";
13489ee7876kaiw	case ODK_HWPATCH: return "HWPATCH";
13499ee7876kaiw	case ODK_FILL: return "FILL";
13509ee7876kaiw	case ODK_TAGS: return "TAGS";
13519ee7876kaiw	case ODK_HWAND: return "HWAND";
13529ee7876kaiw	case ODK_HWOR: return "HWOR";
13539ee7876kaiw	case ODK_GP_GROUP: return "GP_GROUP";
13549ee7876kaiw	case ODK_IDENT: return "IDENT";
13559ee7876kaiw	default:
13569ee7876kaiw		snprintf(s_kind, sizeof(s_kind), "<unknown: %u>", kind);
13579ee7876kaiw		return (s_kind);
13589ee7876kaiw	}
13599ee7876kaiw}
13609ee7876kaiw
13619ee7876kaiwstatic const char *
13629ee7876kaiwtop_tag(unsigned int tag)
13639ee7876kaiw{
13649ee7876kaiw	static char s_top_tag[32];
13659ee7876kaiw
13669ee7876kaiw	switch (tag) {
13679ee7876kaiw	case 1: return "File Attributes";
13689ee7876kaiw	case 2: return "Section Attributes";
13699ee7876kaiw	case 3: return "Symbol Attributes";
13709ee7876kaiw	default:
13719ee7876kaiw		snprintf(s_top_tag, sizeof(s_top_tag), "Unknown tag: %u", tag);
13729ee7876kaiw		return (s_top_tag);
13739ee7876kaiw	}
13749ee7876kaiw}
13759ee7876kaiw
13769ee7876kaiwstatic const char *
13779ee7876kaiwaeabi_cpu_arch(uint64_t arch)
13789ee7876kaiw{
13799ee7876kaiw	static char s_cpu_arch[32];
13809ee7876kaiw
13819ee7876kaiw	switch (arch) {
13829ee7876kaiw	case 0: return "Pre-V4";
13839ee7876kaiw	case 1: return "ARM v4";
13849ee7876kaiw	case 2: return "ARM v4T";
13859ee7876kaiw	case 3: return "ARM v5T";
13869ee7876kaiw	case 4: return "ARM v5TE";
13879ee7876kaiw	case 5: return "ARM v5TEJ";
13889ee7876kaiw	case 6: return "ARM v6";
13899ee7876kaiw	case 7: return "ARM v6KZ";
13909ee7876kaiw	case 8: return "ARM v6T2";
13919ee7876kaiw	case 9: return "ARM v6K";
13929ee7876kaiw	case 10: return "ARM v7";
13939ee7876kaiw	case 11: return "ARM v6-M";
13949ee7876kaiw	case 12: return "ARM v6S-M";
13959ee7876kaiw	case 13: return "ARM v7E-M";
13969ee7876kaiw	default:
13979ee7876kaiw		snprintf(s_cpu_arch, sizeof(s_cpu_arch),
13989ee7876kaiw		    "Unknown (%ju)", (uintmax_t) arch);
13999ee7876kaiw		return (s_cpu_arch);
14009ee7876kaiw	}
14019ee7876kaiw}
14029ee7876kaiw
14039ee7876kaiwstatic const char *
14049ee7876kaiwaeabi_cpu_arch_profile(uint64_t pf)
14059ee7876kaiw{
14069ee7876kaiw	static char s_arch_profile[32];
14079ee7876kaiw
14089ee7876kaiw	switch (pf) {
14099ee7876kaiw	case 0:
14109ee7876kaiw		return "Not applicable";
14119ee7876kaiw	case 0x41:		/* 'A' */
14129ee7876kaiw		return "Application Profile";
14139ee7876kaiw	case 0x52:		/* 'R' */
14149ee7876kaiw		return "Real-Time Profile";
14159ee7876kaiw	case 0x4D:		/* 'M' */
14169ee7876kaiw		return "Microcontroller Profile";
14179ee7876kaiw	case 0x53:		/* 'S' */
14189ee7876kaiw		return "Application or Real-Time Profile";
14199ee7876kaiw	default:
14209ee7876kaiw		snprintf(s_arch_profile, sizeof(s_arch_profile),
14219ee7876kaiw		    "Unknown (%ju)\n", (uintmax_t) pf);
14229ee7876kaiw		return (s_arch_profile);
14239ee7876kaiw	}
14249ee7876kaiw}
14259ee7876kaiw
14269ee7876kaiwstatic const char *
14279ee7876kaiwaeabi_arm_isa(uint64_t ai)
14289ee7876kaiw{
14299ee7876kaiw	static char s_ai[32];
14309ee7876kaiw
14319ee7876kaiw	switch (ai) {
14329ee7876kaiw	case 0: return "No";
14339ee7876kaiw	case 1: return "Yes";
14349ee7876kaiw	default:
14359ee7876kaiw		snprintf(s_ai, sizeof(s_ai), "Unknown (%ju)\n",
14369ee7876kaiw		    (uintmax_t) ai);
14379ee7876kaiw		return (s_ai);
14389ee7876kaiw	}
14399ee7876kaiw}
14409ee7876kaiw
14419ee7876kaiwstatic const char *
14429ee7876kaiwaeabi_thumb_isa(uint64_t ti)
14439ee7876kaiw{
14449ee7876kaiw	static char s_ti[32];
14459ee7876kaiw
14469ee7876kaiw	switch (ti) {
14479ee7876kaiw	case 0: return "No";
14489ee7876kaiw	case 1: return "16-bit Thumb";
14499ee7876kaiw	case 2: return "32-bit Thumb";
14509ee7876kaiw	default:
14519ee7876kaiw		snprintf(s_ti, sizeof(s_ti), "Unknown (%ju)\n",
14529ee7876kaiw		    (uintmax_t) ti);
14539ee7876kaiw		return (s_ti);
14549ee7876kaiw	}
14559ee7876kaiw}
14569ee7876kaiw
14579ee7876kaiwstatic const char *
14589ee7876kaiwaeabi_fp_arch(uint64_t fp)
14599ee7876kaiw{
14609ee7876kaiw	static char s_fp_arch[32];
14619ee7876kaiw
14629ee7876kaiw	switch (fp) {
14639ee7876kaiw	case 0: return "No";
14649ee7876kaiw	case 1: return "VFPv1";
14659ee7876kaiw	case 2: return "VFPv2";
14669ee7876kaiw	case 3: return "VFPv3";
14679ee7876kaiw	case 4: return "VFPv3-D16";
14689ee7876kaiw	case 5: return "VFPv4";
14699ee7876kaiw	case 6: return "VFPv4-D16";
14709ee7876kaiw	default:
14719ee7876kaiw		snprintf(s_fp_arch, sizeof(s_fp_arch), "Unknown (%ju)",
14729ee7876kaiw		    (uintmax_t) fp);
14739ee7876kaiw		return (s_fp_arch);
14749ee7876kaiw	}
14759ee7876kaiw}
14769ee7876kaiw
14779ee7876kaiwstatic const char *
14789ee7876kaiwaeabi_wmmx_arch(uint64_t wmmx)
14799ee7876kaiw{
14809ee7876kaiw	static char s_wmmx[32];
14819ee7876kaiw
14829ee7876kaiw	switch (wmmx) {
14839ee7876kaiw	case 0: return "No";
14849ee7876kaiw	case 1: return "WMMXv1";
14859ee7876kaiw	case 2: return "WMMXv2";
14869ee7876kaiw	default:
14879ee7876kaiw		snprintf(s_wmmx, sizeof(s_wmmx), "Unknown (%ju)",
14889ee7876kaiw		    (uintmax_t) wmmx);
14899ee7876kaiw		return (s_wmmx);
14909ee7876kaiw	}
14919ee7876kaiw}
14929ee7876kaiw
14939ee7876kaiwstatic const char *
14949ee7876kaiwaeabi_adv_simd_arch(uint64_t simd)
14959ee7876kaiw{
14969ee7876kaiw	static char s_simd[32];
14979ee7876kaiw
14989ee7876kaiw	switch (simd) {
14999ee7876kaiw	case 0: return "No";
15009ee7876kaiw	case 1: return "NEONv1";
15019ee7876kaiw	case 2: return "NEONv2";
15029ee7876kaiw	default:
15039ee7876kaiw		snprintf(s_simd, sizeof(s_simd), "Unknown (%ju)",
15049ee7876kaiw		    (uintmax_t) simd);
15059ee7876kaiw		return (s_simd);
15069ee7876kaiw	}
15079ee7876kaiw}
15089ee7876kaiw
15099ee7876kaiwstatic const char *
15109ee7876kaiwaeabi_pcs_config(uint64_t pcs)
15119ee7876kaiw{
15129ee7876kaiw	static char s_pcs[32];
15139ee7876kaiw
15149ee7876kaiw	switch (pcs) {
15159ee7876kaiw	case 0: return "None";
15169ee7876kaiw	case 1: return "Bare platform";
15179ee7876kaiw	case 2: return "Linux";
15189ee7876kaiw	case 3: return "Linux DSO";
15199ee7876kaiw	case 4: return "Palm OS 2004";
15209ee7876kaiw	case 5: return "Palm OS (future)";
15219ee7876kaiw	case 6: return "Symbian OS 2004";
15229ee7876kaiw	case 7: return "Symbian OS (future)";
15239ee7876kaiw	default:
15249ee7876kaiw		snprintf(s_pcs, sizeof(s_pcs), "Unknown (%ju)",
15259ee7876kaiw		    (uintmax_t) pcs);
15269ee7876kaiw		return (s_pcs);
15279ee7876kaiw	}
15289ee7876kaiw}
15299ee7876kaiw
15309ee7876kaiwstatic const char *
15319ee7876kaiwaeabi_pcs_r9(uint64_t r9)
15329ee7876kaiw{
15339ee7876kaiw	static char s_r9[32];
15349ee7876kaiw
15359ee7876kaiw	switch (r9) {
15369ee7876kaiw	case 0: return "V6";
15379ee7876kaiw	case 1: return "SB";
15389ee7876kaiw	case 2: return "TLS pointer";
15399ee7876kaiw	case 3: return "Unused";
15409ee7876kaiw	default:
15419ee7876kaiw		snprintf(s_r9, sizeof(s_r9), "Unknown (%ju)", (uintmax_t) r9);
15429ee7876kaiw		return (s_r9);
15439ee7876kaiw	}
15449ee7876kaiw}
15459ee7876kaiw
15469ee7876kaiwstatic const char *
15479ee7876kaiwaeabi_pcs_rw(uint64_t rw)
15489ee7876kaiw{
15499ee7876kaiw	static char s_rw[32];
15509ee7876kaiw
15519ee7876kaiw	switch (rw) {
15529ee7876kaiw	case 0: return "Absolute";
15539ee7876kaiw	case 1: return "PC-relative";
15549ee7876kaiw	case 2: return "SB-relative";
15559ee7876kaiw	case 3: return "None";
15569ee7876kaiw	default:
15579ee7876kaiw		snprintf(s_rw, sizeof(s_rw), "Unknown (%ju)", (uintmax_t) rw);
15589ee7876kaiw		return (s_rw);
15599ee7876kaiw	}
15609ee7876kaiw}
15619ee7876kaiw
15629ee7876kaiwstatic const char *
15639ee7876kaiwaeabi_pcs_ro(uint64_t ro)
15649ee7876kaiw{
15659ee7876kaiw	static char s_ro[32];
15669ee7876kaiw
15679ee7876kaiw	switch (ro) {
15689ee7876kaiw	case 0: return "Absolute";
15699ee7876kaiw	case 1: return "PC-relative";
15709ee7876kaiw	case 2: return "None";
15719ee7876kaiw	default:
15729ee7876kaiw		snprintf(s_ro, sizeof(s_ro), "Unknown (%ju)", (uintmax_t) ro);
15739ee7876kaiw		return (s_ro);
15749ee7876kaiw	}
15759ee7876kaiw}
15769ee7876kaiw
15779ee7876kaiwstatic const char *
15789ee7876kaiwaeabi_pcs_got(uint64_t got)
15799ee7876kaiw{
15809ee7876kaiw	static char s_got[32];
15819ee7876kaiw
15829ee7876kaiw	switch (got) {
15839ee7876kaiw	case 0: return "None";
15849ee7876kaiw	case 1: return "direct";
15859ee7876kaiw	case 2: return "indirect via GOT";
15869ee7876kaiw	default:
15879ee7876kaiw		snprintf(s_got, sizeof(s_got), "Unknown (%ju)",
15889ee7876kaiw		    (uintmax_t) got);
15899ee7876kaiw		return (s_got);
15909ee7876kaiw	}
15919ee7876kaiw}
15929ee7876kaiw
15939ee7876kaiwstatic const char *
15949ee7876kaiwaeabi_pcs_wchar_t(uint64_t wt)
15959ee7876kaiw{
15969ee7876kaiw	static char s_wt[32];
15979ee7876kaiw
15989ee7876kaiw	switch (wt) {
15999ee7876kaiw	case 0: return "None";
16009ee7876kaiw	case 2: return "wchar_t size 2";
16019ee7876kaiw	case 4: return "wchar_t size 4";
16029ee7876kaiw	default:
16039ee7876kaiw		snprintf(s_wt, sizeof(s_wt), "Unknown (%ju)", (uintmax_t) wt);
16049ee7876kaiw		return (s_wt);
16059ee7876kaiw	}
16069ee7876kaiw}
16079ee7876kaiw
16089ee7876kaiwstatic const char *
16099ee7876kaiwaeabi_enum_size(uint64_t es)
16109ee7876kaiw{
16119ee7876kaiw	static char s_es[32];
16129ee7876kaiw
16139ee7876kaiw	switch (es) {
16149ee7876kaiw	case 0: return "None";
16159ee7876kaiw	case 1: return "smallest";
16169ee7876kaiw	case 2: return "32-bit";
16179ee7876kaiw	case 3: return "visible 32-bit";
16189ee7876kaiw	default:
16199ee7876kaiw		snprintf(s_es, sizeof(s_es), "Unknown (%ju)", (uintmax_t) es);
16209ee7876kaiw		return (s_es);
16219ee7876kaiw	}
16229ee7876kaiw}
16239ee7876kaiw
16249ee7876kaiwstatic const char *
16259ee7876kaiwaeabi_align_needed(uint64_t an)
16269ee7876kaiw{
16279ee7876kaiw	static char s_align_n[64];
16289ee7876kaiw
16299ee7876kaiw	switch (an) {
16309ee7876kaiw	case 0: return "No";
16319ee7876kaiw	case 1: return "8-byte align";
16329ee7876kaiw	case 2: return "4-byte align";
16339ee7876kaiw	case 3: return "Reserved";
16349ee7876kaiw	default:
16359ee7876kaiw		if (an >= 4 && an <= 12)
16369ee7876kaiw			snprintf(s_align_n, sizeof(s_align_n), "8-byte align"
16379ee7876kaiw			    " and up to 2^%ju-byte extended align",
16389ee7876kaiw			    (uintmax_t) an);
16399ee7876kaiw		else
16409ee7876kaiw			snprintf(s_align_n, sizeof(s_align_n), "Unknown (%ju)",
16419ee7876kaiw			    (uintmax_t) an);
16429ee7876kaiw		return (s_align_n);
16439ee7876kaiw	}
16449ee7876kaiw}
16459ee7876kaiw
16469ee7876kaiwstatic const char *
16479ee7876kaiwaeabi_align_preserved(uint64_t ap)
16489ee7876kaiw{
16499ee7876kaiw	static char s_align_p[128];
16509ee7876kaiw
16519ee7876kaiw	switch (ap) {
16529ee7876kaiw	case 0: return "No";
16539ee7876kaiw	case 1: return "8-byte align";
16549ee7876kaiw	case 2: return "8-byte align and SP % 8 == 0";
16559ee7876kaiw	case 3: return "Reserved";
16569ee7876kaiw	default:
16579ee7876kaiw		if (ap >= 4 && ap <= 12)
16589ee7876kaiw			snprintf(s_align_p, sizeof(s_align_p), "8-byte align"
16599ee7876kaiw			    " and SP %% 8 == 0 and up to 2^%ju-byte extended"
16609ee7876kaiw			    " align", (uintmax_t) ap);
16619ee7876kaiw		else
16629ee7876kaiw			snprintf(s_align_p, sizeof(s_align_p), "Unknown (%ju)",
16639ee7876kaiw			    (uintmax_t) ap);
16649ee7876kaiw		return (s_align_p);
16659ee7876kaiw	}
16669ee7876kaiw}
16679ee7876kaiw
16689ee7876kaiwstatic const char *
16699ee7876kaiwaeabi_fp_rounding(uint64_t fr)
16709ee7876kaiw{
16719ee7876kaiw	static char s_fp_r[32];
16729ee7876kaiw
16739ee7876kaiw	switch (fr) {
16749ee7876kaiw	case 0: return "Unused";
16759ee7876kaiw	case 1: return "Needed";
16769ee7876kaiw	default:
16779ee7876kaiw		snprintf(s_fp_r, sizeof(s_fp_r), "Unknown (%ju)",
16789ee7876kaiw		    (uintmax_t) fr);
16799ee7876kaiw		return (s_fp_r);
16809ee7876kaiw	}
16819ee7876kaiw}
16829ee7876kaiw
16839ee7876kaiwstatic const char *
16849ee7876kaiwaeabi_fp_denormal(uint64_t fd)
16859ee7876kaiw{
16869ee7876kaiw	static char s_fp_d[32];
16879ee7876kaiw
16889ee7876kaiw	switch (fd) {
16899ee7876kaiw	case 0: return "Unused";
16909ee7876kaiw	case 1: return "Needed";
16919ee7876kaiw	case 2: return "Sign Only";
16929ee7876kaiw	default:
16939ee7876kaiw		snprintf(s_fp_d, sizeof(s_fp_d), "Unknown (%ju)",
16949ee7876kaiw		    (uintmax_t) fd);
16959ee7876kaiw		return (s_fp_d);
16969ee7876kaiw	}
16979ee7876kaiw}
16989ee7876kaiw
16999ee7876kaiwstatic const char *
17009ee7876kaiwaeabi_fp_exceptions(uint64_t fe)
17019ee7876kaiw{
17029ee7876kaiw	static char s_fp_e[32];
17039ee7876kaiw
17049ee7876kaiw	switch (fe) {
17059ee7876kaiw	case 0: return "Unused";
17069ee7876kaiw	case 1: return "Needed";
17079ee7876kaiw	default:
17089ee7876kaiw		snprintf(s_fp_e, sizeof(s_fp_e), "Unknown (%ju)",
17099ee7876kaiw		    (uintmax_t) fe);
17109ee7876kaiw		return (s_fp_e);
17119ee7876kaiw	}
17129ee7876kaiw}
17139ee7876kaiw
17149ee7876kaiwstatic const char *
17159ee7876kaiwaeabi_fp_user_exceptions(uint64_t fu)
17169ee7876kaiw{
17179ee7876kaiw	static char s_fp_u[32];
17189ee7876kaiw
17199ee7876kaiw	switch (fu) {
17209ee7876kaiw	case 0: return "Unused";
17219ee7876kaiw	case 1: return "Needed";
17229ee7876kaiw	default:
17239ee7876kaiw		snprintf(s_fp_u, sizeof(s_fp_u), "Unknown (%ju)",
17249ee7876kaiw		    (uintmax_t) fu);
17259ee7876kaiw		return (s_fp_u);
17269ee7876kaiw	}
17279ee7876kaiw}
17289ee7876kaiw
17299ee7876kaiwstatic const char *
17309ee7876kaiwaeabi_fp_number_model(uint64_t fn)
17319ee7876kaiw{
17329ee7876kaiw	static char s_fp_n[32];
17339ee7876kaiw
17349ee7876kaiw	switch (fn) {
17359ee7876kaiw	case 0: return "Unused";
17369ee7876kaiw	case 1: return "IEEE 754 normal";
17379ee7876kaiw	case 2: return "RTABI";
17389ee7876kaiw	case 3: return "IEEE 754";
17399ee7876kaiw	default:
17409ee7876kaiw		snprintf(s_fp_n, sizeof(s_fp_n), "Unknown (%ju)",
17419ee7876kaiw		    (uintmax_t) fn);
17429ee7876kaiw		return (s_fp_n);
17439ee7876kaiw	}
17449ee7876kaiw}
17459ee7876kaiw
17469ee7876kaiwstatic const char *
17479ee7876kaiwaeabi_fp_16bit_format(uint64_t fp16)
17489ee7876kaiw{
17499ee7876kaiw	static char s_fp_16[64];
17509ee7876kaiw
17519ee7876kaiw	switch (fp16) {
17529ee7876kaiw	case 0: return "None";
17539ee7876kaiw	case 1: return "IEEE 754";
17549ee7876kaiw	case 2: return "VFPv3/Advanced SIMD (alternative format)";
17559ee7876kaiw	default:
17569ee7876kaiw		snprintf(s_fp_16, sizeof(s_fp_16), "Unknown (%ju)",
17579ee7876kaiw		    (uintmax_t) fp16);
17589ee7876kaiw		return (s_fp_16);
17599ee7876kaiw	}
17609ee7876kaiw}
17619ee7876kaiw
17629ee7876kaiwstatic const char *
17639ee7876kaiwaeabi_mpext(uint64_t mp)
17649ee7876kaiw{
17659ee7876kaiw	static char s_mp[32];
17669ee7876kaiw
17679ee7876kaiw	switch (mp) {
17689ee7876kaiw	case 0: return "Not allowed";
17699ee7876kaiw	case 1: return "Allowed";
17709ee7876kaiw	default:
17719ee7876kaiw		snprintf(s_mp, sizeof(s_mp), "Unknown (%ju)",
17729ee7876kaiw		    (uintmax_t) mp);
17739ee7876kaiw		return (s_mp);
17749ee7876kaiw	}
17759ee7876kaiw}
17769ee7876kaiw
17779ee7876kaiwstatic const char *
17789ee7876kaiwaeabi_div(uint64_t du)
17799ee7876kaiw{
17809ee7876kaiw	static char s_du[32];
17819ee7876kaiw
17829ee7876kaiw	switch (du) {
17839ee7876kaiw	case 0: return "Yes (V7-R/V7-M)";
17849ee7876kaiw	case 1: return "No";
17859ee7876kaiw	case 2: return "Yes (V7-A)";
17869ee7876kaiw	default:
17879ee7876kaiw		snprintf(s_du, sizeof(s_du), "Unknown (%ju)",
17889ee7876kaiw		    (uintmax_t) du);
17899ee7876kaiw		return (s_du);
17909ee7876kaiw	}
17919ee7876kaiw}
17929ee7876kaiw
17939ee7876kaiwstatic const char *
17949ee7876kaiwaeabi_t2ee(uint64_t t2ee)
17959ee7876kaiw{
17969ee7876kaiw	static char s_t2ee[32];
17979ee7876kaiw
17989ee7876kaiw	switch (t2ee) {
17999ee7876kaiw	case 0: return "Not allowed";
18009ee7876kaiw	case 1: return "Allowed";
18019ee7876kaiw	default:
18029ee7876kaiw		snprintf(s_t2ee, sizeof(s_t2ee), "Unknown(%ju)",
18039ee7876kaiw		    (uintmax_t) t2ee);
18049ee7876kaiw		return (s_t2ee);
18059ee7876kaiw	}
18069ee7876kaiw
18079ee7876kaiw}
18089ee7876kaiw
18099ee7876kaiwstatic const char *
18109ee7876kaiwaeabi_hardfp(uint64_t hfp)
18119ee7876kaiw{
18129ee7876kaiw	static char s_hfp[32];
18139ee7876kaiw
18149ee7876kaiw	switch (hfp) {
18159ee7876kaiw	case 0: return "Tag_FP_arch";
18169ee7876kaiw	case 1: return "only SP";
18179ee7876kaiw	case 2: return "only DP";
18189ee7876kaiw	case 3: return "both SP and DP";
18199ee7876kaiw	default:
18209ee7876kaiw		snprintf(s_hfp, sizeof(s_hfp), "Unknown (%ju)",
18219ee7876kaiw		    (uintmax_t) hfp);
18229ee7876kaiw		return (s_hfp);
18239ee7876kaiw	}
18249ee7876kaiw}
18259ee7876kaiw
18269ee7876kaiwstatic const char *
18279ee7876kaiwaeabi_vfp_args(uint64_t va)
18289ee7876kaiw{
18299ee7876kaiw	static char s_va[32];
18309ee7876kaiw
18319ee7876kaiw	switch (va) {
18329ee7876kaiw	case 0: return "AAPCS (base variant)";
18339ee7876kaiw	case 1: return "AAPCS (VFP variant)";
18349ee7876kaiw	case 2: return "toolchain-specific";
18359ee7876kaiw	default:
18369ee7876kaiw		snprintf(s_va, sizeof(s_va), "Unknown (%ju)", (uintmax_t) va);
18379ee7876kaiw		return (s_va);
18389ee7876kaiw	}
18399ee7876kaiw}
18409ee7876kaiw
18419ee7876kaiwstatic const char *
18429ee7876kaiwaeabi_wmmx_args(uint64_t wa)
18439ee7876kaiw{
18449ee7876kaiw	static char s_wa[32];
18459ee7876kaiw
18469ee7876kaiw	switch (wa) {
18479ee7876kaiw	case 0: return "AAPCS (base variant)";
18489ee7876kaiw	case 1: return "Intel WMMX";
18499ee7876kaiw	case 2: return "toolchain-specific";
18509ee7876kaiw	default:
18519ee7876kaiw		snprintf(s_wa, sizeof(s_wa), "Unknown(%ju)", (uintmax_t) wa);
18529ee7876kaiw		return (s_wa);
18539ee7876kaiw	}
18549ee7876kaiw}
18559ee7876kaiw
18569ee7876kaiwstatic const char *
18579ee7876kaiwaeabi_unaligned_access(uint64_t ua)
18589ee7876kaiw{
18599ee7876kaiw	static char s_ua[32];
18609ee7876kaiw
18619ee7876kaiw	switch (ua) {
18629ee7876kaiw	case 0: return "Not allowed";
18639ee7876kaiw	case 1: return "Allowed";
18649ee7876kaiw	default:
18659ee7876kaiw		snprintf(s_ua, sizeof(s_ua), "Unknown(%ju)", (uintmax_t) ua);
18669ee7876kaiw		return (s_ua);
18679ee7876kaiw	}
18689ee7876kaiw}
18699ee7876kaiw
18709ee7876kaiwstatic const char *
18719ee7876kaiwaeabi_fp_hpext(uint64_t fh)
18729ee7876kaiw{
18739ee7876kaiw	static char s_fh[32];
18749ee7876kaiw
18759ee7876kaiw	switch (fh) {
18769ee7876kaiw	case 0: return "Not allowed";
18779ee7876kaiw	case 1: return "Allowed";
18789ee7876kaiw	default:
18799ee7876kaiw		snprintf(s_fh, sizeof(s_fh), "Unknown(%ju)", (uintmax_t) fh);
18809ee7876kaiw		return (s_fh);
18819ee7876kaiw	}
18829ee7876kaiw}
18839ee7876kaiw
18849ee7876kaiwstatic const char *
18859ee7876kaiwaeabi_optm_goal(uint64_t og)
18869ee7876kaiw{
18879ee7876kaiw	static char s_og[32];
18889ee7876kaiw
18899ee7876kaiw	switch (og) {
18909ee7876kaiw	case 0: return "None";
18919ee7876kaiw	case 1: return "Speed";
18929ee7876kaiw	case 2: return "Speed aggressive";
18939ee7876kaiw	case 3: return "Space";
18949ee7876kaiw	case 4: return "Space aggressive";
18959ee7876kaiw	case 5: return "Debugging";
18969ee7876kaiw	case 6: return "Best Debugging";
18979ee7876kaiw	default:
18989ee7876kaiw		snprintf(s_og, sizeof(s_og), "Unknown(%ju)", (uintmax_t) og);
18999ee7876kaiw		return (s_og);
19009ee7876kaiw	}
19019ee7876kaiw}
19029ee7876kaiw
19039ee7876kaiwstatic const char *
19049ee7876kaiwaeabi_fp_optm_goal(uint64_t fog)
19059ee7876kaiw{
19069ee7876kaiw	static char s_fog[32];
19079ee7876kaiw
19089ee7876kaiw	switch (fog) {
19099ee7876kaiw	case 0: return "None";
19109ee7876kaiw	case 1: return "Speed";
19119ee7876kaiw	case 2: return "Speed aggressive";
19129ee7876kaiw	case 3: return "Space";
19139ee7876kaiw	case 4: return "Space aggressive";
19149ee7876kaiw	case 5: return "Accurary";
19159ee7876kaiw	case 6: return "Best Accurary";
19169ee7876kaiw	default:
19179ee7876kaiw		snprintf(s_fog, sizeof(s_fog), "Unknown(%ju)",
19189ee7876kaiw		    (uintmax_t) fog);
19199ee7876kaiw		return (s_fog);
19209ee7876kaiw	}
19219ee7876kaiw}
19229ee7876kaiw
19239ee7876kaiwstatic const char *
19249ee7876kaiwaeabi_virtual(uint64_t vt)
19259ee7876kaiw{
19269ee7876kaiw	static char s_virtual[64];
19279ee7876kaiw
19289ee7876kaiw	switch (vt) {
19299ee7876kaiw	case 0: return "No";
19309ee7876kaiw	case 1: return "TrustZone";
19319ee7876kaiw	case 2: return "Virtualization extension";
19329ee7876kaiw	case 3: return "TrustZone and virtualization extension";
19339ee7876kaiw	default:
19349ee7876kaiw		snprintf(s_virtual, sizeof(s_virtual), "Unknown(%ju)",
19359ee7876kaiw		    (uintmax_t) vt);
19369ee7876kaiw		return (s_virtual);
19379ee7876kaiw	}
19389ee7876kaiw}
19399ee7876kaiw
19409ee7876kaiwstatic struct {
19419ee7876kaiw	uint64_t tag;
19429ee7876kaiw	const char *s_tag;
19439ee7876kaiw	const char *(*get_desc)(uint64_t val);
19449ee7876kaiw} aeabi_tags[] = {
19459ee7876kaiw	{4, "Tag_CPU_raw_name", NULL},
19469ee7876kaiw	{5, "Tag_CPU_name", NULL},
19479ee7876kaiw	{6, "Tag_CPU_arch", aeabi_cpu_arch},
19489ee7876kaiw	{7, "Tag_CPU_arch_profile", aeabi_cpu_arch_profile},
19499ee7876kaiw	{8, "Tag_ARM_ISA_use", aeabi_arm_isa},
19509ee7876kaiw	{9, "Tag_THUMB_ISA_use", aeabi_thumb_isa},
19519ee7876kaiw	{10, "Tag_FP_arch", aeabi_fp_arch},
19529ee7876kaiw	{11, "Tag_WMMX_arch", aeabi_wmmx_arch},
19539ee7876kaiw	{12, "Tag_Advanced_SIMD_arch", aeabi_adv_simd_arch},
19549ee7876kaiw	{13, "Tag_PCS_config", aeabi_pcs_config},
19559ee7876kaiw	{14, "Tag_ABI_PCS_R9_use", aeabi_pcs_r9},
19569ee7876kaiw	{15, "Tag_ABI_PCS_RW_data", aeabi_pcs_rw},
19579ee7876kaiw	{16, "Tag_ABI_PCS_RO_data", aeabi_pcs_ro},
19589ee7876kaiw	{17, "Tag_ABI_PCS_GOT_use", aeabi_pcs_got},
19599ee7876kaiw	{18, "Tag_ABI_PCS_wchar_t", aeabi_pcs_wchar_t},
19609ee7876kaiw	{19, "Tag_ABI_FP_rounding", aeabi_fp_rounding},
19619ee7876kaiw	{20, "Tag_ABI_FP_denormal", aeabi_fp_denormal},
19629ee7876kaiw	{21, "Tag_ABI_FP_exceptions", aeabi_fp_exceptions},
19639ee7876kaiw	{22, "Tag_ABI_FP_user_exceptions", aeabi_fp_user_exceptions},
19649ee7876kaiw	{23, "Tag_ABI_FP_number_model", aeabi_fp_number_model},
19659ee7876kaiw	{24, "Tag_ABI_align_needed", aeabi_align_needed},
19669ee7876kaiw	{25, "Tag_ABI_align_preserved", aeabi_align_preserved},
19679ee7876kaiw	{26, "Tag_ABI_enum_size", aeabi_enum_size},
19689ee7876kaiw	{27, "Tag_ABI_HardFP_use", aeabi_hardfp},
19699ee7876kaiw	{28, "Tag_ABI_VFP_args", aeabi_vfp_args},
19709ee7876kaiw	{29, "Tag_ABI_WMMX_args", aeabi_wmmx_args},
19719ee7876kaiw	{30, "Tag_ABI_optimization_goals", aeabi_optm_goal},
19729ee7876kaiw	{31, "Tag_ABI_FP_optimization_goals", aeabi_fp_optm_goal},
19739ee7876kaiw	{32, "Tag_compatibility", NULL},
19749ee7876kaiw	{34, "Tag_CPU_unaligned_access", aeabi_unaligned_access},
19759ee7876kaiw	{36, "Tag_FP_HP_extension", aeabi_fp_hpext},
19769ee7876kaiw	{38, "Tag_ABI_FP_16bit_format", aeabi_fp_16bit_format},
19779ee7876kaiw	{42, "Tag_MPextension_use", aeabi_mpext},
19789ee7876kaiw	{44, "Tag_DIV_use", aeabi_div},
19799ee7876kaiw	{64, "Tag_nodefaults", NULL},
19809ee7876kaiw	{65, "Tag_also_compatible_with", NULL},
19819ee7876kaiw	{66, "Tag_T2EE_use", aeabi_t2ee},
19829ee7876kaiw	{67, "Tag_conformance", NULL},
19839ee7876kaiw	{68, "Tag_Virtualization_use", aeabi_virtual},
19849ee7876kaiw	{70, "Tag_MPextension_use", aeabi_mpext},
19859ee7876kaiw};
19869ee7876kaiw
19879ee7876kaiwstatic const char *
19889ee7876kaiwmips_abi_fp(uint64_t fp)
19899ee7876kaiw{
19909ee7876kaiw	static char s_mips_abi_fp[64];
19919ee7876kaiw
19929ee7876kaiw	switch (fp) {
19939ee7876kaiw	case 0: return "N/A";
19949ee7876kaiw	case 1: return "Hard float (double precision)";
19959ee7876kaiw	case 2: return "Hard float (single precision)";
19969ee7876kaiw	case 3: return "Soft float";
19979ee7876kaiw	case 4: return "64-bit float (-mips32r2 -mfp64)";
19989ee7876kaiw	default:
19999ee7876kaiw		snprintf(s_mips_abi_fp, sizeof(s_mips_abi_fp), "Unknown(%ju)",
20009ee7876kaiw		    (uintmax_t) fp);
20019ee7876kaiw		return (s_mips_abi_fp);
20029ee7876kaiw	}
20039ee7876kaiw}
20049ee7876kaiw
20059ee7876kaiwstatic const char *
20069ee7876kaiwppc_abi_fp(uint64_t fp)
2007