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