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 371976Sab196087 381976Sab196087 391976Sab196087 /* Instantiate a local copy of conv_map2str() from _conv.h */ 401976Sab196087 DEFINE_conv_map2str 411976Sab196087 421976Sab196087 431976Sab196087 440Sstevel@tonic-gate const char * 451976Sab196087 conv_ehdr_class(uchar_t class, int fmt_flags) 460Sstevel@tonic-gate { 471618Srie static char string[CONV_INV_STRSIZE]; 481618Srie static const Msg classes[] = { 491976Sab196087 MSG_ELFCLASSNONE, MSG_ELFCLASS32, MSG_ELFCLASS64 501976Sab196087 }; 511976Sab196087 static const Msg classes_alt[] = { 521976Sab196087 MSG_ELFCLASSNONE_ALT, MSG_ELFCLASS32_ALT, MSG_ELFCLASS64_ALT 531618Srie }; 540Sstevel@tonic-gate 551976Sab196087 return (conv_map2str(string, sizeof (string), class, fmt_flags, 561976Sab196087 ARRAY_NELTS(classes), classes, classes_alt, classes_alt)); 570Sstevel@tonic-gate } 580Sstevel@tonic-gate 590Sstevel@tonic-gate const char * 601976Sab196087 conv_ehdr_data(uchar_t data, int fmt_flags) 610Sstevel@tonic-gate { 621618Srie static char string[CONV_INV_STRSIZE]; 631618Srie static const Msg datas[] = { 641976Sab196087 MSG_ELFDATANONE, MSG_ELFDATA2LSB, MSG_ELFDATA2MSB 651976Sab196087 }; 661976Sab196087 static const Msg datas_dump[] = { 671976Sab196087 MSG_ELFDATANONE_ALT, MSG_ELFDATA2LSB_ALT1, MSG_ELFDATA2MSB_ALT1 681976Sab196087 }; 691976Sab196087 static const Msg datas_file[] = { 701976Sab196087 MSG_ELFDATANONE_ALT, MSG_ELFDATA2LSB_ALT2, MSG_ELFDATA2MSB_ALT2 711618Srie }; 720Sstevel@tonic-gate 731976Sab196087 return (conv_map2str(string, sizeof (string), data, fmt_flags, 741976Sab196087 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 }; 1111976Sab196087 static const Msg machines_alt[EM_NUM] = { 1121976Sab196087 MSG_EM_NONE_ALT, MSG_EM_M32_ALT, MSG_EM_SPARC_ALT, 1131976Sab196087 MSG_EM_386_ALT, MSG_EM_68K_ALT, MSG_EM_88K_ALT, 1141976Sab196087 MSG_EM_486_ALT, MSG_EM_860_ALT, MSG_EM_MIPS_ALT, 1151976Sab196087 MSG_EM_UNKNOWN9, MSG_EM_MIPS_RS3_LE_ALT, MSG_EM_RS6000_ALT, 1161976Sab196087 MSG_EM_UNKNOWN12, MSG_EM_UNKNOWN13, MSG_EM_UNKNOWN14, 1171976Sab196087 MSG_EM_PA_RISC_ALT, MSG_EM_nCUBE_ALT, MSG_EM_VPP500_ALT, 1181976Sab196087 MSG_EM_SPARC32PLUS_ALT, MSG_EM_UNKNOWN19, MSG_EM_PPC_ALT, 1191976Sab196087 MSG_EM_PPC64_ALT, MSG_EM_UNKNOWN22, MSG_EM_UNKNOWN23, 1201976Sab196087 MSG_EM_UNKNOWN24, MSG_EM_UNKNOWN25, MSG_EM_UNKNOWN26, 1211976Sab196087 MSG_EM_UNKNOWN27, MSG_EM_UNKNOWN28, MSG_EM_UNKNOWN29, 1221976Sab196087 MSG_EM_UNKNOWN30, MSG_EM_UNKNOWN31, MSG_EM_UNKNOWN32, 1231976Sab196087 MSG_EM_UNKNOWN33, MSG_EM_UNKNOWN34, MSG_EM_UNKNOWN35, 1241976Sab196087 MSG_EM_Y800, MSG_EM_FR20, MSG_EM_RH32, 1251976Sab196087 MSG_EM_RCE, MSG_EM_ARM_ALT, MSG_EM_ALPHA_ALT, 1261976Sab196087 MSG_EM_SH, MSG_EM_SPARCV9_ALT, MSG_EM_TRICORE, 1271976Sab196087 MSG_EM_ARC, MSG_EM_H8_300, MSG_EM_H8_300H, 1281976Sab196087 MSG_EM_H8S, MSG_EM_H8_500, MSG_EM_IA_64_ALT, 1291976Sab196087 MSG_EM_MIPS_X, MSG_EM_COLDFIRE, MSG_EM_68HC12, 1301976Sab196087 MSG_EM_MMA, MSG_EM_PCP, MSG_EM_NCPU, 1311976Sab196087 MSG_EM_NDR1, MSG_EM_STARCORE, MSG_EM_ME16, 1321976Sab196087 MSG_EM_ST100, MSG_EM_TINYJ, MSG_EM_AMD64_ALT, 1331976Sab196087 MSG_EM_UNKNOWN63, MSG_EM_UNKNOWN64, MSG_EM_UNKNOWN65, 1341976Sab196087 MSG_EM_FX66, MSG_EM_ST9PLUS, MSG_EM_ST7, 1351976Sab196087 MSG_EM_68HC16, MSG_EM_68HC11, MSG_EM_68HC08, 1361976Sab196087 MSG_EM_68HC05, MSG_EM_SVX, MSG_EM_ST19, 1371976Sab196087 MSG_EM_VAX_ALT, MSG_EM_CRIS, MSG_EM_JAVELIN, 1381976Sab196087 MSG_EM_FIREPATH, MSG_EM_ZSP, MSG_EM_MMIX, 1391976Sab196087 MSG_EM_HUANY, MSG_EM_PRISM, MSG_EM_AVR, 1401976Sab196087 MSG_EM_FR30, MSG_EM_D10V, MSG_EM_D30V, 1411976Sab196087 MSG_EM_V850, MSG_EM_M32R, MSG_EM_MN10300, 1421976Sab196087 MSG_EM_MN10200, MSG_EM_PJ, MSG_EM_OPENRISC, 1431976Sab196087 MSG_EM_ARC_A5, MSG_EM_XTENSA 1441976Sab196087 }; 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 * 1501976Sab196087 conv_ehdr_mach(Half machine, int fmt_flags) 1511618Srie { 1521618Srie static char string[CONV_INV_STRSIZE]; 1531618Srie 1541976Sab196087 return (conv_map2str(string, sizeof (string), machine, fmt_flags, 1551976Sab196087 ARRAY_NELTS(machines), machines, machines_alt, machines_alt)); 1560Sstevel@tonic-gate } 1570Sstevel@tonic-gate 1581976Sab196087 1590Sstevel@tonic-gate const char * 1601976Sab196087 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 }; 1671976Sab196087 static const Msg etypes_alt[] = { 1681976Sab196087 MSG_ET_NONE_ALT, MSG_ET_REL_ALT, MSG_ET_EXEC_ALT, 1691976Sab196087 MSG_ET_DYN_ALT, MSG_ET_CORE_ALT 1701976Sab196087 }; 1710Sstevel@tonic-gate 1721976Sab196087 if (etype == ET_SUNWPSEUDO) { 1731976Sab196087 return ((fmt_flags & CONV_FMTALTMASK) 1741976Sab196087 ? MSG_ORIG(MSG_ET_SUNWPSEUDO_ALT) 1751976Sab196087 : MSG_ORIG(MSG_ET_SUNWPSEUDO)); 1761976Sab196087 } 1771976Sab196087 1781976Sab196087 return (conv_map2str(string, sizeof (string), etype, fmt_flags, 1791976Sab196087 ARRAY_NELTS(etypes), etypes, etypes_alt, etypes_alt)); 1801976Sab196087 1810Sstevel@tonic-gate } 1820Sstevel@tonic-gate 1830Sstevel@tonic-gate const char * 1841976Sab196087 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 }; 1901976Sab196087 static const Msg versions_alt[] = { 1911976Sab196087 MSG_EV_NONE_ALT, MSG_EV_CURRENT_ALT 1921976Sab196087 }; 1930Sstevel@tonic-gate 1941976Sab196087 return (conv_map2str(string, sizeof (string), version, fmt_flags, 1951976Sab196087 ARRAY_NELTS(versions), versions, versions_alt, versions_alt)); 1960Sstevel@tonic-gate } 1970Sstevel@tonic-gate 198*2352Sab196087 #define EFLAGSZ CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \ 199*2352Sab196087 MSG_EF_SPARCV9_TSO_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 200*2352Sab196087 MSG_EF_SPARC_SUN_US1_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 201*2352Sab196087 MSG_EF_SPARC_HAL_R1_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 202*2352Sab196087 MSG_EF_SPARC_SUN_US3_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 203*2352Sab196087 CONV_INV_STRSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_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 }; 223*2352Sab196087 static const char *leading_str_arr[2]; 224*2352Sab196087 static CONV_EXPN_FIELD_ARG conv_arg = { string, sizeof (string), vda, 225*2352Sab196087 leading_str_arr }; 226*2352Sab196087 227*2352Sab196087 const char **lstr = leading_str_arr; 2280Sstevel@tonic-gate 2290Sstevel@tonic-gate /* 2301618Srie * Non-SPARC architectures presently provide no known flags. 2310Sstevel@tonic-gate */ 2320Sstevel@tonic-gate if ((mach == EM_SPARCV9) || (((mach == EM_SPARC) || 2330Sstevel@tonic-gate (mach == EM_SPARC32PLUS)) && flags)) { 2341618Srie /* 2351618Srie * Valid vendor extension bits for SPARCV9. These must be 2361618Srie * updated along with elf_SPARC.h. 2371618Srie */ 2380Sstevel@tonic-gate 239*2352Sab196087 conv_arg.oflags = conv_arg.rflags = flags; 2401618Srie if ((mach == EM_SPARCV9) && (flags <= EF_SPARCV9_RMO)) { 241*2352Sab196087 *lstr++ = MSG_ORIG(mm_flags[flags & EF_SPARCV9_MM]); 242*2352Sab196087 conv_arg.rflags &= ~EF_SPARCV9_MM; 2430Sstevel@tonic-gate } 244*2352Sab196087 *lstr = NULL; 2450Sstevel@tonic-gate 246*2352Sab196087 (void) conv_expn_field(&conv_arg); 2470Sstevel@tonic-gate 2481618Srie return (string); 2491618Srie } 2501976Sab196087 return (conv_invalid_val(string, EFLAGSZ, flags, CONV_FMT_DECIMAL)); 2510Sstevel@tonic-gate } 2520Sstevel@tonic-gate 2530Sstevel@tonic-gate /* 2540Sstevel@tonic-gate * A generic means of returning additional information for a rejected file in 2550Sstevel@tonic-gate * terms of a string. 2560Sstevel@tonic-gate */ 2570Sstevel@tonic-gate const char * 2581618Srie conv_reject_desc(Rej_desc * rej) 2590Sstevel@tonic-gate { 2601618Srie static char string[CONV_INV_STRSIZE]; 2610Sstevel@tonic-gate 2620Sstevel@tonic-gate ushort_t type = rej->rej_type; 2630Sstevel@tonic-gate uint_t info = rej->rej_info; 2640Sstevel@tonic-gate 2650Sstevel@tonic-gate if (type == SGS_REJ_MACH) 2660Sstevel@tonic-gate /* LINTED */ 2671976Sab196087 return (conv_ehdr_mach((Half)info, 0)); 2680Sstevel@tonic-gate else if (type == SGS_REJ_CLASS) 2690Sstevel@tonic-gate /* LINTED */ 2701976Sab196087 return (conv_ehdr_class((uchar_t)info, 0)); 2710Sstevel@tonic-gate else if (type == SGS_REJ_DATA) 2720Sstevel@tonic-gate /* LINTED */ 2731976Sab196087 return (conv_ehdr_data((uchar_t)info, 0)); 2740Sstevel@tonic-gate else if (type == SGS_REJ_TYPE) 2750Sstevel@tonic-gate /* LINTED */ 2761976Sab196087 return (conv_ehdr_type((Half)info, 0)); 2770Sstevel@tonic-gate else if ((type == SGS_REJ_BADFLAG) || (type == SGS_REJ_MISFLAG) || 2780Sstevel@tonic-gate (type == SGS_REJ_HAL) || (type == SGS_REJ_US3)) 2790Sstevel@tonic-gate /* 2800Sstevel@tonic-gate * Only called from ld.so.1, thus M_MACH is hardcoded. 2810Sstevel@tonic-gate */ 2821618Srie return (conv_ehdr_flags(M_MACH, (Word)info)); 2830Sstevel@tonic-gate else if (type == SGS_REJ_UNKFILE) 2840Sstevel@tonic-gate return ((const char *)0); 2850Sstevel@tonic-gate else if ((type == SGS_REJ_STR) || (type == SGS_REJ_HWCAP_1)) { 2860Sstevel@tonic-gate if (rej->rej_str) 2870Sstevel@tonic-gate return ((const char *)rej->rej_str); 2880Sstevel@tonic-gate else 2890Sstevel@tonic-gate return (MSG_ORIG(MSG_STR_EMPTY)); 2900Sstevel@tonic-gate } else 2911618Srie return (conv_invalid_val(string, CONV_INV_STRSIZE, info, 2921976Sab196087 CONV_FMT_DECIMAL)); 2930Sstevel@tonic-gate } 294