xref: /onnv-gate/usr/src/cmd/sgs/libconv/common/elf.c (revision 1976:f0691a145b7e)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51618Srie  * Common Development and Distribution License (the "License").
61618Srie  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
211618Srie 
220Sstevel@tonic-gate /*
231618Srie  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate /*
290Sstevel@tonic-gate  * String conversion routines for ELF header attributes.
300Sstevel@tonic-gate  */
310Sstevel@tonic-gate #include	<stdio.h>
320Sstevel@tonic-gate #include	<string.h>
330Sstevel@tonic-gate #include	"_conv.h"
340Sstevel@tonic-gate #include	"elf_msg.h"
350Sstevel@tonic-gate #include	<sys/elf_SPARC.h>
360Sstevel@tonic-gate 
37*1976Sab196087 
38*1976Sab196087 
39*1976Sab196087 /* Instantiate a local copy of conv_map2str() from _conv.h */
40*1976Sab196087 DEFINE_conv_map2str
41*1976Sab196087 
42*1976Sab196087 
43*1976Sab196087 
440Sstevel@tonic-gate const char *
45*1976Sab196087 conv_ehdr_class(uchar_t class, int fmt_flags)
460Sstevel@tonic-gate {
471618Srie 	static char		string[CONV_INV_STRSIZE];
481618Srie 	static const Msg	classes[] = {
49*1976Sab196087 		MSG_ELFCLASSNONE, MSG_ELFCLASS32, MSG_ELFCLASS64
50*1976Sab196087 	};
51*1976Sab196087 	static const Msg	classes_alt[] = {
52*1976Sab196087 		MSG_ELFCLASSNONE_ALT, MSG_ELFCLASS32_ALT, MSG_ELFCLASS64_ALT
531618Srie 	};
540Sstevel@tonic-gate 
55*1976Sab196087 	return (conv_map2str(string, sizeof (string), class, fmt_flags,
56*1976Sab196087 		ARRAY_NELTS(classes), classes, classes_alt, classes_alt));
570Sstevel@tonic-gate }
580Sstevel@tonic-gate 
590Sstevel@tonic-gate const char *
60*1976Sab196087 conv_ehdr_data(uchar_t data, int fmt_flags)
610Sstevel@tonic-gate {
621618Srie 	static char		string[CONV_INV_STRSIZE];
631618Srie 	static const Msg	datas[] = {
64*1976Sab196087 		MSG_ELFDATANONE, MSG_ELFDATA2LSB, MSG_ELFDATA2MSB
65*1976Sab196087 	};
66*1976Sab196087 	static const Msg	datas_dump[] = {
67*1976Sab196087 		MSG_ELFDATANONE_ALT, MSG_ELFDATA2LSB_ALT1, MSG_ELFDATA2MSB_ALT1
68*1976Sab196087 	};
69*1976Sab196087 	static const Msg	datas_file[] = {
70*1976Sab196087 		MSG_ELFDATANONE_ALT, MSG_ELFDATA2LSB_ALT2, MSG_ELFDATA2MSB_ALT2
711618Srie 	};
720Sstevel@tonic-gate 
73*1976Sab196087 	return (conv_map2str(string, sizeof (string), data, fmt_flags,
74*1976Sab196087 		ARRAY_NELTS(datas), datas, datas_dump, datas_file));
750Sstevel@tonic-gate }
760Sstevel@tonic-gate 
770Sstevel@tonic-gate static const Msg machines[EM_NUM] = {
781618Srie 	MSG_EM_NONE,		MSG_EM_M32,		MSG_EM_SPARC,
791618Srie 	MSG_EM_386,		MSG_EM_68K,		MSG_EM_88K,
801618Srie 	MSG_EM_486,		MSG_EM_860,		MSG_EM_MIPS,
811618Srie 	MSG_EM_UNKNOWN9,	MSG_EM_MIPS_RS3_LE,	MSG_EM_RS6000,
821618Srie 	MSG_EM_UNKNOWN12,	MSG_EM_UNKNOWN13,	MSG_EM_UNKNOWN14,
831618Srie 	MSG_EM_PA_RISC,		MSG_EM_nCUBE,		MSG_EM_VPP500,
841618Srie 	MSG_EM_SPARC32PLUS,	MSG_EM_UNKNOWN19,	MSG_EM_PPC,
851618Srie 	MSG_EM_PPC64,		MSG_EM_UNKNOWN22,	MSG_EM_UNKNOWN23,
861618Srie 	MSG_EM_UNKNOWN24,	MSG_EM_UNKNOWN25,	MSG_EM_UNKNOWN26,
871618Srie 	MSG_EM_UNKNOWN27,	MSG_EM_UNKNOWN28,	MSG_EM_UNKNOWN29,
881618Srie 	MSG_EM_UNKNOWN30,	MSG_EM_UNKNOWN31,	MSG_EM_UNKNOWN32,
891618Srie 	MSG_EM_UNKNOWN33,	MSG_EM_UNKNOWN34,	MSG_EM_UNKNOWN35,
901618Srie 	MSG_EM_Y800,		MSG_EM_FR20,		MSG_EM_RH32,
911618Srie 	MSG_EM_RCE,		MSG_EM_ARM,		MSG_EM_ALPHA,
921618Srie 	MSG_EM_SH,		MSG_EM_SPARCV9,		MSG_EM_TRICORE,
931618Srie 	MSG_EM_ARC,		MSG_EM_H8_300,		MSG_EM_H8_300H,
941618Srie 	MSG_EM_H8S,		MSG_EM_H8_500,		MSG_EM_IA_64,
951618Srie 	MSG_EM_MIPS_X,		MSG_EM_COLDFIRE,	MSG_EM_68HC12,
961618Srie 	MSG_EM_MMA,		MSG_EM_PCP,		MSG_EM_NCPU,
971618Srie 	MSG_EM_NDR1,		MSG_EM_STARCORE,	MSG_EM_ME16,
981618Srie 	MSG_EM_ST100,		MSG_EM_TINYJ,		MSG_EM_AMD64,
991618Srie 	MSG_EM_UNKNOWN63,	MSG_EM_UNKNOWN64,	MSG_EM_UNKNOWN65,
1001618Srie 	MSG_EM_FX66,		MSG_EM_ST9PLUS,		MSG_EM_ST7,
1011618Srie 	MSG_EM_68HC16,		MSG_EM_68HC11,		MSG_EM_68HC08,
1021618Srie 	MSG_EM_68HC05,		MSG_EM_SVX,		MSG_EM_ST19,
1031618Srie 	MSG_EM_VAX,		MSG_EM_CRIS,		MSG_EM_JAVELIN,
1041618Srie 	MSG_EM_FIREPATH,	MSG_EM_ZSP,		MSG_EM_MMIX,
1051618Srie 	MSG_EM_HUANY,		MSG_EM_PRISM,		MSG_EM_AVR,
1061618Srie 	MSG_EM_FR30,		MSG_EM_D10V,		MSG_EM_D30V,
1071618Srie 	MSG_EM_V850,		MSG_EM_M32R,		MSG_EM_MN10300,
1081618Srie 	MSG_EM_MN10200,		MSG_EM_PJ,		MSG_EM_OPENRISC,
1091618Srie 	MSG_EM_ARC_A5,		MSG_EM_XTENSA
1100Sstevel@tonic-gate };
111*1976Sab196087 static const Msg machines_alt[EM_NUM] = {
112*1976Sab196087 	MSG_EM_NONE_ALT,	MSG_EM_M32_ALT,		MSG_EM_SPARC_ALT,
113*1976Sab196087 	MSG_EM_386_ALT,		MSG_EM_68K_ALT,		MSG_EM_88K_ALT,
114*1976Sab196087 	MSG_EM_486_ALT,		MSG_EM_860_ALT,		MSG_EM_MIPS_ALT,
115*1976Sab196087 	MSG_EM_UNKNOWN9,	MSG_EM_MIPS_RS3_LE_ALT,	MSG_EM_RS6000_ALT,
116*1976Sab196087 	MSG_EM_UNKNOWN12,	MSG_EM_UNKNOWN13,	MSG_EM_UNKNOWN14,
117*1976Sab196087 	MSG_EM_PA_RISC_ALT,	MSG_EM_nCUBE_ALT,	MSG_EM_VPP500_ALT,
118*1976Sab196087 	MSG_EM_SPARC32PLUS_ALT,	MSG_EM_UNKNOWN19,	MSG_EM_PPC_ALT,
119*1976Sab196087 	MSG_EM_PPC64_ALT,	MSG_EM_UNKNOWN22,	MSG_EM_UNKNOWN23,
120*1976Sab196087 	MSG_EM_UNKNOWN24,	MSG_EM_UNKNOWN25,	MSG_EM_UNKNOWN26,
121*1976Sab196087 	MSG_EM_UNKNOWN27,	MSG_EM_UNKNOWN28,	MSG_EM_UNKNOWN29,
122*1976Sab196087 	MSG_EM_UNKNOWN30,	MSG_EM_UNKNOWN31,	MSG_EM_UNKNOWN32,
123*1976Sab196087 	MSG_EM_UNKNOWN33,	MSG_EM_UNKNOWN34,	MSG_EM_UNKNOWN35,
124*1976Sab196087 	MSG_EM_Y800,		MSG_EM_FR20,		MSG_EM_RH32,
125*1976Sab196087 	MSG_EM_RCE,		MSG_EM_ARM_ALT,		MSG_EM_ALPHA_ALT,
126*1976Sab196087 	MSG_EM_SH,		MSG_EM_SPARCV9_ALT,	MSG_EM_TRICORE,
127*1976Sab196087 	MSG_EM_ARC,		MSG_EM_H8_300,		MSG_EM_H8_300H,
128*1976Sab196087 	MSG_EM_H8S,		MSG_EM_H8_500,		MSG_EM_IA_64_ALT,
129*1976Sab196087 	MSG_EM_MIPS_X,		MSG_EM_COLDFIRE,	MSG_EM_68HC12,
130*1976Sab196087 	MSG_EM_MMA,		MSG_EM_PCP,		MSG_EM_NCPU,
131*1976Sab196087 	MSG_EM_NDR1,		MSG_EM_STARCORE,	MSG_EM_ME16,
132*1976Sab196087 	MSG_EM_ST100,		MSG_EM_TINYJ,		MSG_EM_AMD64_ALT,
133*1976Sab196087 	MSG_EM_UNKNOWN63,	MSG_EM_UNKNOWN64,	MSG_EM_UNKNOWN65,
134*1976Sab196087 	MSG_EM_FX66,		MSG_EM_ST9PLUS,		MSG_EM_ST7,
135*1976Sab196087 	MSG_EM_68HC16,		MSG_EM_68HC11,		MSG_EM_68HC08,
136*1976Sab196087 	MSG_EM_68HC05,		MSG_EM_SVX,		MSG_EM_ST19,
137*1976Sab196087 	MSG_EM_VAX_ALT,		MSG_EM_CRIS,		MSG_EM_JAVELIN,
138*1976Sab196087 	MSG_EM_FIREPATH,	MSG_EM_ZSP,		MSG_EM_MMIX,
139*1976Sab196087 	MSG_EM_HUANY,		MSG_EM_PRISM,		MSG_EM_AVR,
140*1976Sab196087 	MSG_EM_FR30,		MSG_EM_D10V,		MSG_EM_D30V,
141*1976Sab196087 	MSG_EM_V850,		MSG_EM_M32R,		MSG_EM_MN10300,
142*1976Sab196087 	MSG_EM_MN10200,		MSG_EM_PJ,		MSG_EM_OPENRISC,
143*1976Sab196087 	MSG_EM_ARC_A5,		MSG_EM_XTENSA
144*1976Sab196087 };
1450Sstevel@tonic-gate #if	(EM_NUM != (EM_XTENSA + 1))
1460Sstevel@tonic-gate #error	"EM_NUM has grown"
1470Sstevel@tonic-gate #endif
1481618Srie 
1491618Srie const char *
150*1976Sab196087 conv_ehdr_mach(Half machine, int fmt_flags)
1511618Srie {
1521618Srie 	static char	string[CONV_INV_STRSIZE];
1531618Srie 
154*1976Sab196087 	return (conv_map2str(string, sizeof (string), machine, fmt_flags,
155*1976Sab196087 		ARRAY_NELTS(machines), machines, machines_alt, machines_alt));
1560Sstevel@tonic-gate }
1570Sstevel@tonic-gate 
158*1976Sab196087 
1590Sstevel@tonic-gate const char *
160*1976Sab196087 conv_ehdr_type(Half etype, int fmt_flags)
1610Sstevel@tonic-gate {
1621618Srie 	static char		string[CONV_INV_STRSIZE];
1631618Srie 	static const Msg	etypes[] = {
1641618Srie 		MSG_ET_NONE,		MSG_ET_REL,		MSG_ET_EXEC,
1651618Srie 		MSG_ET_DYN,		MSG_ET_CORE
1661618Srie 	};
167*1976Sab196087 	static const Msg	etypes_alt[] = {
168*1976Sab196087 		MSG_ET_NONE_ALT,	MSG_ET_REL_ALT,		MSG_ET_EXEC_ALT,
169*1976Sab196087 		MSG_ET_DYN_ALT,		MSG_ET_CORE_ALT
170*1976Sab196087 	};
1710Sstevel@tonic-gate 
172*1976Sab196087 	if (etype == ET_SUNWPSEUDO) {
173*1976Sab196087 		return ((fmt_flags & CONV_FMTALTMASK)
174*1976Sab196087 			? MSG_ORIG(MSG_ET_SUNWPSEUDO_ALT)
175*1976Sab196087 			: MSG_ORIG(MSG_ET_SUNWPSEUDO));
176*1976Sab196087 	}
177*1976Sab196087 
178*1976Sab196087 	return (conv_map2str(string, sizeof (string), etype, fmt_flags,
179*1976Sab196087 		ARRAY_NELTS(etypes), etypes, etypes_alt, etypes_alt));
180*1976Sab196087 
1810Sstevel@tonic-gate }
1820Sstevel@tonic-gate 
1830Sstevel@tonic-gate const char *
184*1976Sab196087 conv_ehdr_vers(Word version, int fmt_flags)
1850Sstevel@tonic-gate {
1861618Srie 	static char		string[CONV_INV_STRSIZE];
1871618Srie 	static const Msg	versions[] = {
1881618Srie 		MSG_EV_NONE,		MSG_EV_CURRENT
1891618Srie 	};
190*1976Sab196087 	static const Msg	versions_alt[] = {
191*1976Sab196087 		MSG_EV_NONE_ALT,	MSG_EV_CURRENT_ALT
192*1976Sab196087 	};
1930Sstevel@tonic-gate 
194*1976Sab196087 	return (conv_map2str(string, sizeof (string), version, fmt_flags,
195*1976Sab196087 		ARRAY_NELTS(versions), versions, versions_alt, versions_alt));
1960Sstevel@tonic-gate }
1970Sstevel@tonic-gate 
1980Sstevel@tonic-gate #define	EFLAGSZ	MSG_GBL_OSQBRKT_SIZE + \
1990Sstevel@tonic-gate 		MSG_EF_SPARCV9_TSO_SIZE + \
2000Sstevel@tonic-gate 		MSG_EF_SPARC_SUN_US1_SIZE + \
2010Sstevel@tonic-gate 		MSG_EF_SPARC_HAL_R1_SIZE + \
2020Sstevel@tonic-gate 		MSG_EF_SPARC_SUN_US3_SIZE + \
2031618Srie 		CONV_INV_STRSIZE + MSG_GBL_CSQBRKT_SIZE
2040Sstevel@tonic-gate 
2050Sstevel@tonic-gate /*
2061618Srie  * Make a string representation of the e_flags field.
2070Sstevel@tonic-gate  */
2080Sstevel@tonic-gate const char *
2091618Srie conv_ehdr_flags(Half mach, Word flags)
2100Sstevel@tonic-gate {
2111618Srie 	static char	string[EFLAGSZ];
2121618Srie 	static Val_desc vda[] = {
2131618Srie 		{ EF_SPARC_32PLUS,	MSG_ORIG(MSG_EF_SPARC_32PLUS) },
2141618Srie 		{ EF_SPARC_SUN_US1,	MSG_ORIG(MSG_EF_SPARC_SUN_US1) },
2151618Srie 		{ EF_SPARC_HAL_R1,	MSG_ORIG(MSG_EF_SPARC_HAL_R1) },
2161618Srie 		{ EF_SPARC_SUN_US3,	MSG_ORIG(MSG_EF_SPARC_SUN_US3) },
2171618Srie 		{ 0,			0 }
2181618Srie 	};
2191618Srie 	static const Msg mm_flags[] = {
2201618Srie 		MSG_EF_SPARCV9_TSO,	MSG_EF_SPARCV9_PSO,
2211618Srie 		MSG_EF_SPARCV9_RMO
2221618Srie 	};
2231618Srie 	Word		_flags = flags;
2240Sstevel@tonic-gate 
2250Sstevel@tonic-gate 	/*
2261618Srie 	 * Non-SPARC architectures presently provide no known flags.
2270Sstevel@tonic-gate 	 */
2280Sstevel@tonic-gate 	if ((mach == EM_SPARCV9) || (((mach == EM_SPARC) ||
2290Sstevel@tonic-gate 	    (mach == EM_SPARC32PLUS)) && flags)) {
2301618Srie 		/*
2311618Srie 		 * Valid vendor extension bits for SPARCV9.  These must be
2321618Srie 		 * updated along with elf_SPARC.h.
2331618Srie 		 */
2340Sstevel@tonic-gate 		(void) strcpy(string, MSG_ORIG(MSG_GBL_OSQBRKT));
2350Sstevel@tonic-gate 
2361618Srie 		if ((mach == EM_SPARCV9) && (flags <= EF_SPARCV9_RMO)) {
2371618Srie 		    if (strlcat(string,
2381618Srie 			MSG_ORIG(mm_flags[flags & EF_SPARCV9_MM]),
2391618Srie 			EFLAGSZ) >= EFLAGSZ)
2401618Srie 			    return (conv_invalid_val(string, EFLAGSZ,
2411618Srie 				flags, 0));
2421618Srie 		    _flags &= ~EF_SPARCV9_MM;
2430Sstevel@tonic-gate 		}
2440Sstevel@tonic-gate 
2451618Srie 		if (conv_expn_field(string, EFLAGSZ, vda, flags, _flags, 0, 0))
2461618Srie 			(void) strlcat(string, MSG_ORIG(MSG_GBL_CSQBRKT),
2471618Srie 			    EFLAGSZ);
2480Sstevel@tonic-gate 
2491618Srie 		return (string);
2501618Srie 	}
251*1976Sab196087 	return (conv_invalid_val(string, EFLAGSZ, flags, CONV_FMT_DECIMAL));
2520Sstevel@tonic-gate }
2530Sstevel@tonic-gate 
2540Sstevel@tonic-gate /*
2550Sstevel@tonic-gate  * A generic means of returning additional information for a rejected file in
2560Sstevel@tonic-gate  * terms of a string.
2570Sstevel@tonic-gate  */
2580Sstevel@tonic-gate const char *
2591618Srie conv_reject_desc(Rej_desc * rej)
2600Sstevel@tonic-gate {
2611618Srie 	static char	string[CONV_INV_STRSIZE];
2620Sstevel@tonic-gate 
2630Sstevel@tonic-gate 	ushort_t	type = rej->rej_type;
2640Sstevel@tonic-gate 	uint_t		info = rej->rej_info;
2650Sstevel@tonic-gate 
2660Sstevel@tonic-gate 	if (type == SGS_REJ_MACH)
2670Sstevel@tonic-gate 		/* LINTED */
268*1976Sab196087 		return (conv_ehdr_mach((Half)info, 0));
2690Sstevel@tonic-gate 	else if (type == SGS_REJ_CLASS)
2700Sstevel@tonic-gate 		/* LINTED */
271*1976Sab196087 		return (conv_ehdr_class((uchar_t)info, 0));
2720Sstevel@tonic-gate 	else if (type == SGS_REJ_DATA)
2730Sstevel@tonic-gate 		/* LINTED */
274*1976Sab196087 		return (conv_ehdr_data((uchar_t)info, 0));
2750Sstevel@tonic-gate 	else if (type == SGS_REJ_TYPE)
2760Sstevel@tonic-gate 		/* LINTED */
277*1976Sab196087 		return (conv_ehdr_type((Half)info, 0));
2780Sstevel@tonic-gate 	else if ((type == SGS_REJ_BADFLAG) || (type == SGS_REJ_MISFLAG) ||
2790Sstevel@tonic-gate 	    (type == SGS_REJ_HAL) || (type == SGS_REJ_US3))
2800Sstevel@tonic-gate 		/*
2810Sstevel@tonic-gate 		 * Only called from ld.so.1, thus M_MACH is hardcoded.
2820Sstevel@tonic-gate 		 */
2831618Srie 		return (conv_ehdr_flags(M_MACH, (Word)info));
2840Sstevel@tonic-gate 	else if (type == SGS_REJ_UNKFILE)
2850Sstevel@tonic-gate 		return ((const char *)0);
2860Sstevel@tonic-gate 	else if ((type == SGS_REJ_STR) || (type == SGS_REJ_HWCAP_1)) {
2870Sstevel@tonic-gate 		if (rej->rej_str)
2880Sstevel@tonic-gate 			return ((const char *)rej->rej_str);
2890Sstevel@tonic-gate 		else
2900Sstevel@tonic-gate 			return (MSG_ORIG(MSG_STR_EMPTY));
2910Sstevel@tonic-gate 	} else
2921618Srie 		return (conv_invalid_val(string, CONV_INV_STRSIZE, info,
293*1976Sab196087 		    CONV_FMT_DECIMAL));
2940Sstevel@tonic-gate }
295