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 5*1618Srie * Common Development and Distribution License (the "License"). 6*1618Srie * 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 */ 21*1618Srie 220Sstevel@tonic-gate /* 23*1618Srie * 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 370Sstevel@tonic-gate const char * 38*1618Srie conv_ehdr_class(uchar_t class) 390Sstevel@tonic-gate { 40*1618Srie static char string[CONV_INV_STRSIZE]; 41*1618Srie static const Msg classes[] = { 42*1618Srie MSG_ELFCLASSNONE, MSG_ELFCLASS32, MSG_ELFCLASS64 43*1618Srie }; 440Sstevel@tonic-gate 450Sstevel@tonic-gate if (class >= ELFCLASSNUM) 46*1618Srie return (conv_invalid_val(string, CONV_INV_STRSIZE, class, 0)); 470Sstevel@tonic-gate else 480Sstevel@tonic-gate return (MSG_ORIG(classes[class])); 490Sstevel@tonic-gate } 500Sstevel@tonic-gate 510Sstevel@tonic-gate const char * 52*1618Srie conv_ehdr_data(uchar_t data) 530Sstevel@tonic-gate { 54*1618Srie static char string[CONV_INV_STRSIZE]; 55*1618Srie static const Msg datas[] = { 56*1618Srie MSG_ELFDATANONE, MSG_ELFDATA2LSB, MSG_ELFDATA2MSB 57*1618Srie }; 580Sstevel@tonic-gate 590Sstevel@tonic-gate if (data >= ELFDATANUM) 60*1618Srie return (conv_invalid_val(string, CONV_INV_STRSIZE, data, 0)); 610Sstevel@tonic-gate else 620Sstevel@tonic-gate return (MSG_ORIG(datas[data])); 630Sstevel@tonic-gate } 640Sstevel@tonic-gate 650Sstevel@tonic-gate static const Msg machines[EM_NUM] = { 66*1618Srie MSG_EM_NONE, MSG_EM_M32, MSG_EM_SPARC, 67*1618Srie MSG_EM_386, MSG_EM_68K, MSG_EM_88K, 68*1618Srie MSG_EM_486, MSG_EM_860, MSG_EM_MIPS, 69*1618Srie MSG_EM_UNKNOWN9, MSG_EM_MIPS_RS3_LE, MSG_EM_RS6000, 70*1618Srie MSG_EM_UNKNOWN12, MSG_EM_UNKNOWN13, MSG_EM_UNKNOWN14, 71*1618Srie MSG_EM_PA_RISC, MSG_EM_nCUBE, MSG_EM_VPP500, 72*1618Srie MSG_EM_SPARC32PLUS, MSG_EM_UNKNOWN19, MSG_EM_PPC, 73*1618Srie MSG_EM_PPC64, MSG_EM_UNKNOWN22, MSG_EM_UNKNOWN23, 74*1618Srie MSG_EM_UNKNOWN24, MSG_EM_UNKNOWN25, MSG_EM_UNKNOWN26, 75*1618Srie MSG_EM_UNKNOWN27, MSG_EM_UNKNOWN28, MSG_EM_UNKNOWN29, 76*1618Srie MSG_EM_UNKNOWN30, MSG_EM_UNKNOWN31, MSG_EM_UNKNOWN32, 77*1618Srie MSG_EM_UNKNOWN33, MSG_EM_UNKNOWN34, MSG_EM_UNKNOWN35, 78*1618Srie MSG_EM_Y800, MSG_EM_FR20, MSG_EM_RH32, 79*1618Srie MSG_EM_RCE, MSG_EM_ARM, MSG_EM_ALPHA, 80*1618Srie MSG_EM_SH, MSG_EM_SPARCV9, MSG_EM_TRICORE, 81*1618Srie MSG_EM_ARC, MSG_EM_H8_300, MSG_EM_H8_300H, 82*1618Srie MSG_EM_H8S, MSG_EM_H8_500, MSG_EM_IA_64, 83*1618Srie MSG_EM_MIPS_X, MSG_EM_COLDFIRE, MSG_EM_68HC12, 84*1618Srie MSG_EM_MMA, MSG_EM_PCP, MSG_EM_NCPU, 85*1618Srie MSG_EM_NDR1, MSG_EM_STARCORE, MSG_EM_ME16, 86*1618Srie MSG_EM_ST100, MSG_EM_TINYJ, MSG_EM_AMD64, 87*1618Srie MSG_EM_UNKNOWN63, MSG_EM_UNKNOWN64, MSG_EM_UNKNOWN65, 88*1618Srie MSG_EM_FX66, MSG_EM_ST9PLUS, MSG_EM_ST7, 89*1618Srie MSG_EM_68HC16, MSG_EM_68HC11, MSG_EM_68HC08, 90*1618Srie MSG_EM_68HC05, MSG_EM_SVX, MSG_EM_ST19, 91*1618Srie MSG_EM_VAX, MSG_EM_CRIS, MSG_EM_JAVELIN, 92*1618Srie MSG_EM_FIREPATH, MSG_EM_ZSP, MSG_EM_MMIX, 93*1618Srie MSG_EM_HUANY, MSG_EM_PRISM, MSG_EM_AVR, 94*1618Srie MSG_EM_FR30, MSG_EM_D10V, MSG_EM_D30V, 95*1618Srie MSG_EM_V850, MSG_EM_M32R, MSG_EM_MN10300, 96*1618Srie MSG_EM_MN10200, MSG_EM_PJ, MSG_EM_OPENRISC, 97*1618Srie MSG_EM_ARC_A5, MSG_EM_XTENSA 980Sstevel@tonic-gate }; 990Sstevel@tonic-gate #if (EM_NUM != (EM_XTENSA + 1)) 1000Sstevel@tonic-gate #error "EM_NUM has grown" 1010Sstevel@tonic-gate #endif 102*1618Srie 103*1618Srie const char * 104*1618Srie conv_ehdr_mach(Half machine) 105*1618Srie { 106*1618Srie static char string[CONV_INV_STRSIZE]; 107*1618Srie 1080Sstevel@tonic-gate if (machine >= (EM_NUM)) 109*1618Srie return (conv_invalid_val(string, CONV_INV_STRSIZE, machine, 0)); 1100Sstevel@tonic-gate else 1110Sstevel@tonic-gate return (MSG_ORIG(machines[machine])); 1120Sstevel@tonic-gate } 1130Sstevel@tonic-gate 1140Sstevel@tonic-gate const char * 115*1618Srie conv_ehdr_type(Half etype) 1160Sstevel@tonic-gate { 117*1618Srie static char string[CONV_INV_STRSIZE]; 118*1618Srie static const Msg etypes[] = { 119*1618Srie MSG_ET_NONE, MSG_ET_REL, MSG_ET_EXEC, 120*1618Srie MSG_ET_DYN, MSG_ET_CORE 121*1618Srie }; 1220Sstevel@tonic-gate 1230Sstevel@tonic-gate if (etype == ET_SUNWPSEUDO) 1240Sstevel@tonic-gate return (MSG_ORIG(MSG_ET_SUNWPSEUDO)); 1250Sstevel@tonic-gate else if (etype >= ET_NUM) 126*1618Srie return (conv_invalid_val(string, CONV_INV_STRSIZE, etype, 0)); 1270Sstevel@tonic-gate else 1280Sstevel@tonic-gate return (MSG_ORIG(etypes[etype])); 1290Sstevel@tonic-gate } 1300Sstevel@tonic-gate 1310Sstevel@tonic-gate const char * 132*1618Srie conv_ehdr_vers(Word version) 1330Sstevel@tonic-gate { 134*1618Srie static char string[CONV_INV_STRSIZE]; 135*1618Srie static const Msg versions[] = { 136*1618Srie MSG_EV_NONE, MSG_EV_CURRENT 137*1618Srie }; 1380Sstevel@tonic-gate 1390Sstevel@tonic-gate if (version >= EV_NUM) 140*1618Srie return (conv_invalid_val(string, CONV_INV_STRSIZE, version, 0)); 1410Sstevel@tonic-gate else 1420Sstevel@tonic-gate return (MSG_ORIG(versions[version])); 1430Sstevel@tonic-gate } 1440Sstevel@tonic-gate 1450Sstevel@tonic-gate #define EFLAGSZ MSG_GBL_OSQBRKT_SIZE + \ 1460Sstevel@tonic-gate MSG_EF_SPARCV9_TSO_SIZE + \ 1470Sstevel@tonic-gate MSG_EF_SPARC_SUN_US1_SIZE + \ 1480Sstevel@tonic-gate MSG_EF_SPARC_HAL_R1_SIZE + \ 1490Sstevel@tonic-gate MSG_EF_SPARC_SUN_US3_SIZE + \ 150*1618Srie CONV_INV_STRSIZE + MSG_GBL_CSQBRKT_SIZE 1510Sstevel@tonic-gate 1520Sstevel@tonic-gate /* 153*1618Srie * Make a string representation of the e_flags field. 1540Sstevel@tonic-gate */ 1550Sstevel@tonic-gate const char * 156*1618Srie conv_ehdr_flags(Half mach, Word flags) 1570Sstevel@tonic-gate { 158*1618Srie static char string[EFLAGSZ]; 159*1618Srie static Val_desc vda[] = { 160*1618Srie { EF_SPARC_32PLUS, MSG_ORIG(MSG_EF_SPARC_32PLUS) }, 161*1618Srie { EF_SPARC_SUN_US1, MSG_ORIG(MSG_EF_SPARC_SUN_US1) }, 162*1618Srie { EF_SPARC_HAL_R1, MSG_ORIG(MSG_EF_SPARC_HAL_R1) }, 163*1618Srie { EF_SPARC_SUN_US3, MSG_ORIG(MSG_EF_SPARC_SUN_US3) }, 164*1618Srie { 0, 0 } 165*1618Srie }; 166*1618Srie static const Msg mm_flags[] = { 167*1618Srie MSG_EF_SPARCV9_TSO, MSG_EF_SPARCV9_PSO, 168*1618Srie MSG_EF_SPARCV9_RMO 169*1618Srie }; 170*1618Srie Word _flags = flags; 1710Sstevel@tonic-gate 1720Sstevel@tonic-gate /* 173*1618Srie * Non-SPARC architectures presently provide no known flags. 1740Sstevel@tonic-gate */ 1750Sstevel@tonic-gate if ((mach == EM_SPARCV9) || (((mach == EM_SPARC) || 1760Sstevel@tonic-gate (mach == EM_SPARC32PLUS)) && flags)) { 177*1618Srie /* 178*1618Srie * Valid vendor extension bits for SPARCV9. These must be 179*1618Srie * updated along with elf_SPARC.h. 180*1618Srie */ 1810Sstevel@tonic-gate (void) strcpy(string, MSG_ORIG(MSG_GBL_OSQBRKT)); 1820Sstevel@tonic-gate 183*1618Srie if ((mach == EM_SPARCV9) && (flags <= EF_SPARCV9_RMO)) { 184*1618Srie if (strlcat(string, 185*1618Srie MSG_ORIG(mm_flags[flags & EF_SPARCV9_MM]), 186*1618Srie EFLAGSZ) >= EFLAGSZ) 187*1618Srie return (conv_invalid_val(string, EFLAGSZ, 188*1618Srie flags, 0)); 189*1618Srie _flags &= ~EF_SPARCV9_MM; 1900Sstevel@tonic-gate } 1910Sstevel@tonic-gate 192*1618Srie if (conv_expn_field(string, EFLAGSZ, vda, flags, _flags, 0, 0)) 193*1618Srie (void) strlcat(string, MSG_ORIG(MSG_GBL_CSQBRKT), 194*1618Srie EFLAGSZ); 1950Sstevel@tonic-gate 196*1618Srie return (string); 197*1618Srie } 198*1618Srie return (conv_invalid_val(string, EFLAGSZ, flags, CONV_INV_DECIMAL)); 1990Sstevel@tonic-gate } 2000Sstevel@tonic-gate 2010Sstevel@tonic-gate /* 2020Sstevel@tonic-gate * A generic means of returning additional information for a rejected file in 2030Sstevel@tonic-gate * terms of a string. 2040Sstevel@tonic-gate */ 2050Sstevel@tonic-gate const char * 206*1618Srie conv_reject_desc(Rej_desc * rej) 2070Sstevel@tonic-gate { 208*1618Srie static char string[CONV_INV_STRSIZE]; 2090Sstevel@tonic-gate 2100Sstevel@tonic-gate ushort_t type = rej->rej_type; 2110Sstevel@tonic-gate uint_t info = rej->rej_info; 2120Sstevel@tonic-gate 2130Sstevel@tonic-gate if (type == SGS_REJ_MACH) 2140Sstevel@tonic-gate /* LINTED */ 215*1618Srie return (conv_ehdr_mach((Half)info)); 2160Sstevel@tonic-gate else if (type == SGS_REJ_CLASS) 2170Sstevel@tonic-gate /* LINTED */ 218*1618Srie return (conv_ehdr_class((uchar_t)info)); 2190Sstevel@tonic-gate else if (type == SGS_REJ_DATA) 2200Sstevel@tonic-gate /* LINTED */ 221*1618Srie return (conv_ehdr_data((uchar_t)info)); 2220Sstevel@tonic-gate else if (type == SGS_REJ_TYPE) 2230Sstevel@tonic-gate /* LINTED */ 224*1618Srie return (conv_ehdr_type((Half)info)); 2250Sstevel@tonic-gate else if ((type == SGS_REJ_BADFLAG) || (type == SGS_REJ_MISFLAG) || 2260Sstevel@tonic-gate (type == SGS_REJ_HAL) || (type == SGS_REJ_US3)) 2270Sstevel@tonic-gate /* 2280Sstevel@tonic-gate * Only called from ld.so.1, thus M_MACH is hardcoded. 2290Sstevel@tonic-gate */ 230*1618Srie return (conv_ehdr_flags(M_MACH, (Word)info)); 2310Sstevel@tonic-gate else if (type == SGS_REJ_UNKFILE) 2320Sstevel@tonic-gate return ((const char *)0); 2330Sstevel@tonic-gate else if ((type == SGS_REJ_STR) || (type == SGS_REJ_HWCAP_1)) { 2340Sstevel@tonic-gate if (rej->rej_str) 2350Sstevel@tonic-gate return ((const char *)rej->rej_str); 2360Sstevel@tonic-gate else 2370Sstevel@tonic-gate return (MSG_ORIG(MSG_STR_EMPTY)); 2380Sstevel@tonic-gate } else 239*1618Srie return (conv_invalid_val(string, CONV_INV_STRSIZE, info, 240*1618Srie CONV_INV_DECIMAL)); 2410Sstevel@tonic-gate } 242