1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 27*0Sstevel@tonic-gate 28*0Sstevel@tonic-gate /* 29*0Sstevel@tonic-gate * String conversion routines for ELF header attributes. 30*0Sstevel@tonic-gate */ 31*0Sstevel@tonic-gate #include <stdio.h> 32*0Sstevel@tonic-gate #include <string.h> 33*0Sstevel@tonic-gate #include "_conv.h" 34*0Sstevel@tonic-gate #include "elf_msg.h" 35*0Sstevel@tonic-gate #include <sys/elf_SPARC.h> 36*0Sstevel@tonic-gate 37*0Sstevel@tonic-gate static const Msg classes[] = { 38*0Sstevel@tonic-gate MSG_ELFCLASSNONE, MSG_ELFCLASS32, MSG_ELFCLASS64 39*0Sstevel@tonic-gate }; 40*0Sstevel@tonic-gate 41*0Sstevel@tonic-gate const char * 42*0Sstevel@tonic-gate conv_eclass_str(uchar_t class) 43*0Sstevel@tonic-gate { 44*0Sstevel@tonic-gate static char string[STRSIZE] = { '\0' }; 45*0Sstevel@tonic-gate 46*0Sstevel@tonic-gate if (class >= ELFCLASSNUM) 47*0Sstevel@tonic-gate return (conv_invalid_str(string, STRSIZE, class, 0)); 48*0Sstevel@tonic-gate else 49*0Sstevel@tonic-gate return (MSG_ORIG(classes[class])); 50*0Sstevel@tonic-gate 51*0Sstevel@tonic-gate } 52*0Sstevel@tonic-gate 53*0Sstevel@tonic-gate static const Msg datas[] = { 54*0Sstevel@tonic-gate MSG_ELFDATANONE, MSG_ELFDATA2LSB, MSG_ELFDATA2MSB 55*0Sstevel@tonic-gate }; 56*0Sstevel@tonic-gate 57*0Sstevel@tonic-gate const char * 58*0Sstevel@tonic-gate conv_edata_str(uchar_t data) 59*0Sstevel@tonic-gate { 60*0Sstevel@tonic-gate static char string[STRSIZE] = { '\0' }; 61*0Sstevel@tonic-gate 62*0Sstevel@tonic-gate if (data >= ELFDATANUM) 63*0Sstevel@tonic-gate return (conv_invalid_str(string, STRSIZE, data, 0)); 64*0Sstevel@tonic-gate else 65*0Sstevel@tonic-gate return (MSG_ORIG(datas[data])); 66*0Sstevel@tonic-gate 67*0Sstevel@tonic-gate } 68*0Sstevel@tonic-gate 69*0Sstevel@tonic-gate static const Msg machines[EM_NUM] = { 70*0Sstevel@tonic-gate MSG_EM_NONE, 71*0Sstevel@tonic-gate MSG_EM_M32, 72*0Sstevel@tonic-gate MSG_EM_SPARC, 73*0Sstevel@tonic-gate MSG_EM_386, 74*0Sstevel@tonic-gate MSG_EM_68K, 75*0Sstevel@tonic-gate MSG_EM_88K, 76*0Sstevel@tonic-gate MSG_EM_486, 77*0Sstevel@tonic-gate MSG_EM_860, 78*0Sstevel@tonic-gate MSG_EM_MIPS, 79*0Sstevel@tonic-gate MSG_EM_UNKNOWN9, 80*0Sstevel@tonic-gate MSG_EM_MIPS_RS3_LE, 81*0Sstevel@tonic-gate MSG_EM_RS6000, 82*0Sstevel@tonic-gate MSG_EM_UNKNOWN12, 83*0Sstevel@tonic-gate MSG_EM_UNKNOWN13, 84*0Sstevel@tonic-gate MSG_EM_UNKNOWN14, 85*0Sstevel@tonic-gate MSG_EM_PA_RISC, 86*0Sstevel@tonic-gate MSG_EM_nCUBE, 87*0Sstevel@tonic-gate MSG_EM_VPP500, 88*0Sstevel@tonic-gate MSG_EM_SPARC32PLUS, 89*0Sstevel@tonic-gate MSG_EM_UNKNOWN19, 90*0Sstevel@tonic-gate MSG_EM_PPC, 91*0Sstevel@tonic-gate MSG_EM_PPC64, 92*0Sstevel@tonic-gate MSG_EM_UNKNOWN22, 93*0Sstevel@tonic-gate MSG_EM_UNKNOWN23, 94*0Sstevel@tonic-gate MSG_EM_UNKNOWN24, 95*0Sstevel@tonic-gate MSG_EM_UNKNOWN25, 96*0Sstevel@tonic-gate MSG_EM_UNKNOWN26, 97*0Sstevel@tonic-gate MSG_EM_UNKNOWN27, 98*0Sstevel@tonic-gate MSG_EM_UNKNOWN28, 99*0Sstevel@tonic-gate MSG_EM_UNKNOWN29, 100*0Sstevel@tonic-gate MSG_EM_UNKNOWN30, 101*0Sstevel@tonic-gate MSG_EM_UNKNOWN31, 102*0Sstevel@tonic-gate MSG_EM_UNKNOWN32, 103*0Sstevel@tonic-gate MSG_EM_UNKNOWN33, 104*0Sstevel@tonic-gate MSG_EM_UNKNOWN34, 105*0Sstevel@tonic-gate MSG_EM_UNKNOWN35, 106*0Sstevel@tonic-gate MSG_EM_Y800, 107*0Sstevel@tonic-gate MSG_EM_FR20, 108*0Sstevel@tonic-gate MSG_EM_RH32, 109*0Sstevel@tonic-gate MSG_EM_RCE, 110*0Sstevel@tonic-gate MSG_EM_ARM, 111*0Sstevel@tonic-gate MSG_EM_ALPHA, 112*0Sstevel@tonic-gate MSG_EM_SH, 113*0Sstevel@tonic-gate MSG_EM_SPARCV9, 114*0Sstevel@tonic-gate MSG_EM_TRICORE, 115*0Sstevel@tonic-gate MSG_EM_ARC, 116*0Sstevel@tonic-gate MSG_EM_H8_300, 117*0Sstevel@tonic-gate MSG_EM_H8_300H, 118*0Sstevel@tonic-gate MSG_EM_H8S, 119*0Sstevel@tonic-gate MSG_EM_H8_500, 120*0Sstevel@tonic-gate MSG_EM_IA_64, 121*0Sstevel@tonic-gate MSG_EM_MIPS_X, 122*0Sstevel@tonic-gate MSG_EM_COLDFIRE, 123*0Sstevel@tonic-gate MSG_EM_68HC12, 124*0Sstevel@tonic-gate MSG_EM_MMA, 125*0Sstevel@tonic-gate MSG_EM_PCP, 126*0Sstevel@tonic-gate MSG_EM_NCPU, 127*0Sstevel@tonic-gate MSG_EM_NDR1, 128*0Sstevel@tonic-gate MSG_EM_STARCORE, 129*0Sstevel@tonic-gate MSG_EM_ME16, 130*0Sstevel@tonic-gate MSG_EM_ST100, 131*0Sstevel@tonic-gate MSG_EM_TINYJ, 132*0Sstevel@tonic-gate MSG_EM_AMD64, 133*0Sstevel@tonic-gate MSG_EM_UNKNOWN63, 134*0Sstevel@tonic-gate MSG_EM_UNKNOWN64, 135*0Sstevel@tonic-gate MSG_EM_UNKNOWN65, 136*0Sstevel@tonic-gate MSG_EM_FX66, 137*0Sstevel@tonic-gate MSG_EM_ST9PLUS, 138*0Sstevel@tonic-gate MSG_EM_ST7, 139*0Sstevel@tonic-gate MSG_EM_68HC16, 140*0Sstevel@tonic-gate MSG_EM_68HC11, 141*0Sstevel@tonic-gate MSG_EM_68HC08, 142*0Sstevel@tonic-gate MSG_EM_68HC05, 143*0Sstevel@tonic-gate MSG_EM_SVX, 144*0Sstevel@tonic-gate MSG_EM_ST19, 145*0Sstevel@tonic-gate MSG_EM_VAX, 146*0Sstevel@tonic-gate MSG_EM_CRIS, 147*0Sstevel@tonic-gate MSG_EM_JAVELIN, 148*0Sstevel@tonic-gate MSG_EM_FIREPATH, 149*0Sstevel@tonic-gate MSG_EM_ZSP, 150*0Sstevel@tonic-gate MSG_EM_MMIX, 151*0Sstevel@tonic-gate MSG_EM_HUANY, 152*0Sstevel@tonic-gate MSG_EM_PRISM, 153*0Sstevel@tonic-gate MSG_EM_AVR, 154*0Sstevel@tonic-gate MSG_EM_FR30, 155*0Sstevel@tonic-gate MSG_EM_D10V, 156*0Sstevel@tonic-gate MSG_EM_D30V, 157*0Sstevel@tonic-gate MSG_EM_V850, 158*0Sstevel@tonic-gate MSG_EM_M32R, 159*0Sstevel@tonic-gate MSG_EM_MN10300, 160*0Sstevel@tonic-gate MSG_EM_MN10200, 161*0Sstevel@tonic-gate MSG_EM_PJ, 162*0Sstevel@tonic-gate MSG_EM_OPENRISC, 163*0Sstevel@tonic-gate MSG_EM_ARC_A5, 164*0Sstevel@tonic-gate MSG_EM_XTENSA 165*0Sstevel@tonic-gate }; 166*0Sstevel@tonic-gate 167*0Sstevel@tonic-gate const char * 168*0Sstevel@tonic-gate conv_emach_str(ushort_t machine) 169*0Sstevel@tonic-gate { 170*0Sstevel@tonic-gate static char string[STRSIZE] = { '\0' }; 171*0Sstevel@tonic-gate 172*0Sstevel@tonic-gate /* 173*0Sstevel@tonic-gate * In order to assure that all values included in sys/elf.h::EM_* are 174*0Sstevel@tonic-gate * included in libconv/elfdump for decoding - we have the below 175*0Sstevel@tonic-gate * #define trap. Each time the machines[] table is updated, make 176*0Sstevel@tonic-gate * sure the following entry is updated. 177*0Sstevel@tonic-gate */ 178*0Sstevel@tonic-gate #if (EM_NUM != (EM_XTENSA + 1)) 179*0Sstevel@tonic-gate #error "EM_NUM has grown" 180*0Sstevel@tonic-gate #endif 181*0Sstevel@tonic-gate if (machine >= (EM_NUM)) 182*0Sstevel@tonic-gate return (conv_invalid_str(string, STRSIZE, machine, 0)); 183*0Sstevel@tonic-gate else 184*0Sstevel@tonic-gate return (MSG_ORIG(machines[machine])); 185*0Sstevel@tonic-gate 186*0Sstevel@tonic-gate } 187*0Sstevel@tonic-gate 188*0Sstevel@tonic-gate static const Msg etypes[] = { 189*0Sstevel@tonic-gate MSG_ET_NONE, MSG_ET_REL, MSG_ET_EXEC, 190*0Sstevel@tonic-gate MSG_ET_DYN, MSG_ET_CORE 191*0Sstevel@tonic-gate }; 192*0Sstevel@tonic-gate 193*0Sstevel@tonic-gate const char * 194*0Sstevel@tonic-gate conv_etype_str(ushort_t etype) 195*0Sstevel@tonic-gate { 196*0Sstevel@tonic-gate static char string[STRSIZE] = { '\0' }; 197*0Sstevel@tonic-gate 198*0Sstevel@tonic-gate if (etype == ET_SUNWPSEUDO) 199*0Sstevel@tonic-gate return (MSG_ORIG(MSG_ET_SUNWPSEUDO)); 200*0Sstevel@tonic-gate else if (etype >= ET_NUM) 201*0Sstevel@tonic-gate return (conv_invalid_str(string, STRSIZE, etype, 0)); 202*0Sstevel@tonic-gate else 203*0Sstevel@tonic-gate return (MSG_ORIG(etypes[etype])); 204*0Sstevel@tonic-gate } 205*0Sstevel@tonic-gate 206*0Sstevel@tonic-gate static const Msg versions[] = { 207*0Sstevel@tonic-gate MSG_EV_NONE, MSG_EV_CURRENT 208*0Sstevel@tonic-gate }; 209*0Sstevel@tonic-gate 210*0Sstevel@tonic-gate const char * 211*0Sstevel@tonic-gate conv_ever_str(uint_t version) 212*0Sstevel@tonic-gate { 213*0Sstevel@tonic-gate static char string[STRSIZE] = { '\0' }; 214*0Sstevel@tonic-gate 215*0Sstevel@tonic-gate if (version >= EV_NUM) 216*0Sstevel@tonic-gate return (conv_invalid_str(string, STRSIZE, version, 0)); 217*0Sstevel@tonic-gate else 218*0Sstevel@tonic-gate return (MSG_ORIG(versions[version])); 219*0Sstevel@tonic-gate } 220*0Sstevel@tonic-gate 221*0Sstevel@tonic-gate 222*0Sstevel@tonic-gate static const Msg mm_flags[] = { 223*0Sstevel@tonic-gate MSG_EF_SPARCV9_TSO, MSG_EF_SPARCV9_PSO, MSG_EF_SPARCV9_RMO 224*0Sstevel@tonic-gate }; 225*0Sstevel@tonic-gate 226*0Sstevel@tonic-gate #define EFLAGSZ MSG_GBL_OSQBRKT_SIZE + \ 227*0Sstevel@tonic-gate MSG_EF_SPARCV9_TSO_SIZE + \ 228*0Sstevel@tonic-gate MSG_EF_SPARC_SUN_US1_SIZE + \ 229*0Sstevel@tonic-gate MSG_EF_SPARC_HAL_R1_SIZE + \ 230*0Sstevel@tonic-gate MSG_EF_SPARC_SUN_US3_SIZE + \ 231*0Sstevel@tonic-gate MSG_GBL_CSQBRKT_SIZE 232*0Sstevel@tonic-gate 233*0Sstevel@tonic-gate /* 234*0Sstevel@tonic-gate * Valid vendor extension bits for SPARCV9. This must be updated along with 235*0Sstevel@tonic-gate * elf_SPARC.h. 236*0Sstevel@tonic-gate */ 237*0Sstevel@tonic-gate const char * 238*0Sstevel@tonic-gate conv_eflags_str(ushort_t mach, uint_t flags) 239*0Sstevel@tonic-gate { 240*0Sstevel@tonic-gate static char string[EFLAGSZ] = { '\0' }; 241*0Sstevel@tonic-gate 242*0Sstevel@tonic-gate /* 243*0Sstevel@tonic-gate * Make a string representation of the e_flags field. If any bogus 244*0Sstevel@tonic-gate * bits are set, then just return a string containing the numeric value. 245*0Sstevel@tonic-gate */ 246*0Sstevel@tonic-gate if ((mach == EM_SPARCV9) || (((mach == EM_SPARC) || 247*0Sstevel@tonic-gate (mach == EM_SPARC32PLUS)) && flags)) { 248*0Sstevel@tonic-gate uint_t _flags = flags; 249*0Sstevel@tonic-gate 250*0Sstevel@tonic-gate (void) strcpy(string, MSG_ORIG(MSG_GBL_OSQBRKT)); 251*0Sstevel@tonic-gate 252*0Sstevel@tonic-gate if (mach == EM_SPARCV9) { 253*0Sstevel@tonic-gate (void) strcat(string, MSG_ORIG(mm_flags[flags & 254*0Sstevel@tonic-gate EF_SPARCV9_MM])); 255*0Sstevel@tonic-gate _flags &= ~EF_SPARCV9_MM; 256*0Sstevel@tonic-gate } 257*0Sstevel@tonic-gate 258*0Sstevel@tonic-gate if (flags & EF_SPARC_32PLUS) { 259*0Sstevel@tonic-gate (void) strcat(string, MSG_ORIG(MSG_EF_SPARC_32PLUS)); 260*0Sstevel@tonic-gate _flags &= ~EF_SPARC_32PLUS; 261*0Sstevel@tonic-gate } 262*0Sstevel@tonic-gate if (flags & EF_SPARC_SUN_US1) { 263*0Sstevel@tonic-gate (void) strcat(string, MSG_ORIG(MSG_EF_SPARC_SUN_US1)); 264*0Sstevel@tonic-gate _flags &= ~EF_SPARC_SUN_US1; 265*0Sstevel@tonic-gate } 266*0Sstevel@tonic-gate if (flags & EF_SPARC_HAL_R1) { 267*0Sstevel@tonic-gate (void) strcat(string, MSG_ORIG(MSG_EF_SPARC_HAL_R1)); 268*0Sstevel@tonic-gate _flags &= ~EF_SPARC_HAL_R1; 269*0Sstevel@tonic-gate } 270*0Sstevel@tonic-gate if (flags & EF_SPARC_SUN_US3) { 271*0Sstevel@tonic-gate (void) strcat(string, MSG_ORIG(MSG_EF_SPARC_SUN_US3)); 272*0Sstevel@tonic-gate _flags &= ~EF_SPARC_SUN_US3; 273*0Sstevel@tonic-gate } 274*0Sstevel@tonic-gate if (_flags) 275*0Sstevel@tonic-gate (void) sprintf(&string[strlen(string)], 276*0Sstevel@tonic-gate MSG_ORIG(MSG_EF_GEN_1_FLAGS), _flags); 277*0Sstevel@tonic-gate 278*0Sstevel@tonic-gate (void) strcat(string, MSG_ORIG(MSG_GBL_CSQBRKT)); 279*0Sstevel@tonic-gate } else 280*0Sstevel@tonic-gate (void) sprintf(string, MSG_ORIG(MSG_EF_GEN_2_FLAGS), flags); 281*0Sstevel@tonic-gate 282*0Sstevel@tonic-gate return (string); 283*0Sstevel@tonic-gate } 284*0Sstevel@tonic-gate 285*0Sstevel@tonic-gate /* 286*0Sstevel@tonic-gate * A generic means of returning additional information for a rejected file in 287*0Sstevel@tonic-gate * terms of a string. 288*0Sstevel@tonic-gate */ 289*0Sstevel@tonic-gate const char * 290*0Sstevel@tonic-gate conv_reject_str(Rej_desc * rej) 291*0Sstevel@tonic-gate { 292*0Sstevel@tonic-gate static char string[STRSIZE] = { '\0' }; 293*0Sstevel@tonic-gate 294*0Sstevel@tonic-gate ushort_t type = rej->rej_type; 295*0Sstevel@tonic-gate uint_t info = rej->rej_info; 296*0Sstevel@tonic-gate 297*0Sstevel@tonic-gate if (type == SGS_REJ_MACH) 298*0Sstevel@tonic-gate /* LINTED */ 299*0Sstevel@tonic-gate return (conv_emach_str((ushort_t)info)); 300*0Sstevel@tonic-gate else if (type == SGS_REJ_CLASS) 301*0Sstevel@tonic-gate /* LINTED */ 302*0Sstevel@tonic-gate return (conv_eclass_str((uchar_t)info)); 303*0Sstevel@tonic-gate else if (type == SGS_REJ_DATA) 304*0Sstevel@tonic-gate /* LINTED */ 305*0Sstevel@tonic-gate return (conv_edata_str((uchar_t)info)); 306*0Sstevel@tonic-gate else if (type == SGS_REJ_TYPE) 307*0Sstevel@tonic-gate /* LINTED */ 308*0Sstevel@tonic-gate return (conv_etype_str((ushort_t)info)); 309*0Sstevel@tonic-gate else if ((type == SGS_REJ_BADFLAG) || (type == SGS_REJ_MISFLAG) || 310*0Sstevel@tonic-gate (type == SGS_REJ_HAL) || (type == SGS_REJ_US3)) 311*0Sstevel@tonic-gate /* 312*0Sstevel@tonic-gate * Only called from ld.so.1, thus M_MACH is hardcoded. 313*0Sstevel@tonic-gate */ 314*0Sstevel@tonic-gate return (conv_eflags_str(M_MACH, info)); 315*0Sstevel@tonic-gate else if (type == SGS_REJ_UNKFILE) 316*0Sstevel@tonic-gate return ((const char *)0); 317*0Sstevel@tonic-gate else if ((type == SGS_REJ_STR) || (type == SGS_REJ_HWCAP_1)) { 318*0Sstevel@tonic-gate if (rej->rej_str) 319*0Sstevel@tonic-gate return ((const char *)rej->rej_str); 320*0Sstevel@tonic-gate else 321*0Sstevel@tonic-gate return (MSG_ORIG(MSG_STR_EMPTY)); 322*0Sstevel@tonic-gate } else 323*0Sstevel@tonic-gate return (conv_invalid_str(string, STRSIZE, info, 1)); 324*0Sstevel@tonic-gate } 325