1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * String conversion routines for symbol attributes. 29 */ 30 #include <stdio.h> 31 #include <_machelf.h> 32 #include <sys/elf_SPARC.h> 33 #include <sys/elf_amd64.h> 34 #include "_conv.h" 35 #include "symbols_msg.h" 36 37 const char * 38 conv_sym_other(uchar_t other, Conv_inv_buf_t *inv_buf) 39 { 40 static const char visibility[7] = { 41 'D', /* STV_DEFAULT */ 42 'I', /* STV_INTERNAL */ 43 'H', /* STV_HIDDEN */ 44 'P', /* STV_PROTECTED */ 45 'X', /* STV_EXPORTED */ 46 'S', /* STV_SINGLETON */ 47 'E' /* STV_ELIMINATE */ 48 }; 49 uchar_t vis = ELF_ST_VISIBILITY(other); 50 uint_t ndx = 0; 51 52 inv_buf->buf[ndx++] = visibility[vis]; 53 54 /* 55 * If unknown bits are present in st_other - throw out a '?' 56 */ 57 if (other & ~MSK_SYM_VISIBILITY) 58 inv_buf->buf[ndx++] = '?'; 59 inv_buf->buf[ndx++] = '\0'; 60 61 return (inv_buf->buf); 62 } 63 64 const char * 65 conv_sym_other_vis(uchar_t value, Conv_fmt_flags_t fmt_flags, 66 Conv_inv_buf_t *inv_buf) 67 { 68 static const Msg vis[] = { 69 MSG_STV_DEFAULT, MSG_STV_INTERNAL, 70 MSG_STV_HIDDEN, MSG_STV_PROTECTED, 71 MSG_STV_EXPORTED, MSG_STV_SINGLETON, 72 MSG_STV_ELIMINATE 73 }; 74 75 static const Msg vis_alt[] = { 76 MSG_STV_DEFAULT_ALT, MSG_STV_INTERNAL_ALT, 77 MSG_STV_HIDDEN_ALT, MSG_STV_PROTECTED_ALT, 78 MSG_STV_EXPORTED_ALT, MSG_STV_SINGLETON_ALT, 79 MSG_STV_ELIMINATE_ALT 80 }; 81 82 if (value >= (sizeof (vis) / sizeof (vis[0]))) 83 return (conv_invalid_val(inv_buf, value, fmt_flags)); 84 85 /* If full ELF names are desired, use those strings */ 86 if (CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_FULLNAME) 87 return (MSG_ORIG(vis_alt[value])); 88 89 /* Default strings */ 90 return (MSG_ORIG(vis[value])); 91 } 92 93 const char * 94 conv_sym_info_type(Half mach, uchar_t type, Conv_fmt_flags_t fmt_flags, 95 Conv_inv_buf_t *inv_buf) 96 { 97 static const Msg types[] = { 98 MSG_STT_NOTYPE, MSG_STT_OBJECT, 99 MSG_STT_FUNC, MSG_STT_SECTION, 100 MSG_STT_FILE, MSG_STT_COMMON, 101 MSG_STT_TLS, MSG_STT_IFUNC 102 }; 103 104 static const Msg types_alt[] = { 105 MSG_STT_NOTYPE_ALT, MSG_STT_OBJECT_ALT, 106 MSG_STT_FUNC_ALT, MSG_STT_SECTION_ALT, 107 MSG_STT_FILE_ALT, MSG_STT_COMMON_ALT, 108 MSG_STT_TLS_ALT, MSG_STT_IFUNC_ALT 109 }; 110 111 if (type < STT_NUM) { 112 /* If full ELF names are desired, use those strings */ 113 if (CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_FULLNAME) 114 return (MSG_ORIG(types_alt[type])); 115 116 /* Default strings */ 117 return (MSG_ORIG(types[type])); 118 } else if (((mach == EM_SPARC) || (mach == EM_SPARC32PLUS) || 119 (mach == EM_SPARCV9)) && (type == STT_SPARC_REGISTER)) { 120 if (CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_FULLNAME) 121 return (MSG_ORIG(MSG_STT_SPARC_REGISTER_ALT)); 122 123 return (MSG_ORIG(MSG_STT_SPARC_REGISTER)); 124 } else { 125 return (conv_invalid_val(inv_buf, type, fmt_flags)); 126 } 127 } 128 129 const char * 130 conv_sym_info_bind(uchar_t bind, Conv_fmt_flags_t fmt_flags, 131 Conv_inv_buf_t *inv_buf) 132 { 133 static const Msg binds[] = { 134 MSG_STB_LOCAL, MSG_STB_GLOBAL, MSG_STB_WEAK 135 }; 136 137 static const Msg binds_alt[] = { 138 MSG_STB_LOCAL_ALT, MSG_STB_GLOBAL_ALT, MSG_STB_WEAK_ALT 139 }; 140 141 if (bind >= STB_NUM) 142 return (conv_invalid_val(inv_buf, bind, fmt_flags)); 143 144 /* If full ELF names are desired, use those strings */ 145 if (CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_FULLNAME) 146 return (MSG_ORIG(binds_alt[bind])); 147 148 /* Default strings */ 149 return (MSG_ORIG(binds[bind])); 150 } 151 152 const char * 153 conv_sym_shndx(Half shndx, Conv_inv_buf_t *inv_buf) 154 { 155 switch (shndx) { 156 case SHN_UNDEF: 157 return (MSG_ORIG(MSG_SHN_UNDEF)); 158 case SHN_SUNW_IGNORE: 159 return (MSG_ORIG(MSG_SHN_SUNW_IGNORE)); 160 case SHN_ABS: 161 return (MSG_ORIG(MSG_SHN_ABS)); 162 case SHN_COMMON: 163 return (MSG_ORIG(MSG_SHN_COMMON)); 164 case SHN_AMD64_LCOMMON: 165 return (MSG_ORIG(MSG_SHN_AMD64_LCOMMON)); 166 case SHN_AFTER: 167 return (MSG_ORIG(MSG_SHN_AFTER)); 168 case SHN_BEFORE: 169 return (MSG_ORIG(MSG_SHN_BEFORE)); 170 case SHN_XINDEX: 171 return (MSG_ORIG(MSG_SHN_XINDEX)); 172 default: 173 return (conv_invalid_val(inv_buf, shndx, CONV_FMT_DECIMAL)); 174 } 175 } 176 177 const char * 178 conv_sym_value(Half mach, uchar_t type, Addr value, Conv_inv_buf_t *inv_buf) 179 { 180 if (((mach == EM_SPARC) || (mach == EM_SPARC32PLUS) || 181 (mach == EM_SPARCV9)) && (type == STT_SPARC_REGISTER)) 182 return (conv_sym_SPARC_value(value, 0, inv_buf)); 183 184 (void) snprintf(inv_buf->buf, sizeof (inv_buf->buf), 185 MSG_ORIG(MSG_SYM_FMT_VAL), EC_ADDR(value)); 186 return (inv_buf->buf); 187 } 188