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 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * String conversion routines for symbol attributes. 30 */ 31 #include <stdio.h> 32 #include <_machelf.h> 33 #include <sys/elf_SPARC.h> 34 #include <sys/elf_amd64.h> 35 #include "_conv.h" 36 #include "symbols_msg.h" 37 38 const char * 39 conv_sym_other(uchar_t other, Conv_inv_buf_t *inv_buf) 40 { 41 static const char visibility[7] = { 42 'D', /* STV_DEFAULT */ 43 'I', /* STV_INTERNAL */ 44 'H', /* STV_HIDDEN */ 45 'P', /* STV_PROTECTED */ 46 'X', /* STV_EXPORTED */ 47 'S', /* STV_SINGLETON */ 48 'E' /* STV_ELIMINATE */ 49 }; 50 uchar_t vis = ELF_ST_VISIBILITY(other); 51 uint_t ndx = 0; 52 53 inv_buf->buf[ndx++] = visibility[vis]; 54 55 /* 56 * If unknown bits are present in st_other - throw out a '?' 57 */ 58 if (other & ~MSK_SYM_VISIBILITY) 59 inv_buf->buf[ndx++] = '?'; 60 inv_buf->buf[ndx++] = '\0'; 61 62 return (inv_buf->buf); 63 } 64 65 const char * 66 conv_sym_other_vis(uchar_t value, Conv_fmt_flags_t fmt_flags, 67 Conv_inv_buf_t *inv_buf) 68 { 69 static const Msg vis[] = { 70 MSG_STV_DEFAULT, MSG_STV_INTERNAL, 71 MSG_STV_HIDDEN, MSG_STV_PROTECTED, 72 MSG_STV_EXPORTED, MSG_STV_SINGLETON, 73 MSG_STV_ELIMINATE 74 }; 75 76 static const Msg vis_alt[] = { 77 MSG_STV_DEFAULT_ALT, MSG_STV_INTERNAL_ALT, 78 MSG_STV_HIDDEN_ALT, MSG_STV_PROTECTED_ALT, 79 MSG_STV_EXPORTED_ALT, MSG_STV_SINGLETON_ALT, 80 MSG_STV_ELIMINATE_ALT 81 }; 82 83 if (value >= (sizeof (vis) / sizeof (vis[0]))) 84 return (conv_invalid_val(inv_buf, value, fmt_flags)); 85 86 /* If full ELF names are desired, use those strings */ 87 if (CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_FULLNAME) 88 return (MSG_ORIG(vis_alt[value])); 89 90 /* Default strings */ 91 return (MSG_ORIG(vis[value])); 92 } 93 94 const char * 95 conv_sym_info_type(Half mach, uchar_t type, Conv_fmt_flags_t fmt_flags, 96 Conv_inv_buf_t *inv_buf) 97 { 98 static const Msg types[] = { 99 MSG_STT_NOTYPE, MSG_STT_OBJECT, 100 MSG_STT_FUNC, MSG_STT_SECTION, 101 MSG_STT_FILE, MSG_STT_COMMON, 102 MSG_STT_TLS 103 }; 104 105 static const Msg types_alt[] = { 106 MSG_STT_NOTYPE_ALT, MSG_STT_OBJECT_ALT, 107 MSG_STT_FUNC_ALT, MSG_STT_SECTION_ALT, 108 MSG_STT_FILE_ALT, MSG_STT_COMMON_ALT, 109 MSG_STT_TLS_ALT 110 }; 111 112 if (type < STT_NUM) { 113 /* If full ELF names are desired, use those strings */ 114 if (CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_FULLNAME) 115 return (MSG_ORIG(types_alt[type])); 116 117 /* Default strings */ 118 return (MSG_ORIG(types[type])); 119 } else if (((mach == EM_SPARC) || (mach == EM_SPARC32PLUS) || 120 (mach == EM_SPARCV9)) && (type == STT_SPARC_REGISTER)) { 121 if (CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_FULLNAME) 122 return (MSG_ORIG(MSG_STT_SPARC_REGISTER_ALT)); 123 124 return (MSG_ORIG(MSG_STT_SPARC_REGISTER)); 125 } else { 126 return (conv_invalid_val(inv_buf, type, fmt_flags)); 127 } 128 } 129 130 const char * 131 conv_sym_info_bind(uchar_t bind, Conv_fmt_flags_t fmt_flags, 132 Conv_inv_buf_t *inv_buf) 133 { 134 static const Msg binds[] = { 135 MSG_STB_LOCAL, MSG_STB_GLOBAL, MSG_STB_WEAK 136 }; 137 138 static const Msg binds_alt[] = { 139 MSG_STB_LOCAL_ALT, MSG_STB_GLOBAL_ALT, MSG_STB_WEAK_ALT 140 }; 141 142 if (bind >= STB_NUM) 143 return (conv_invalid_val(inv_buf, bind, fmt_flags)); 144 145 /* If full ELF names are desired, use those strings */ 146 if (CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_FULLNAME) 147 return (MSG_ORIG(binds_alt[bind])); 148 149 /* Default strings */ 150 return (MSG_ORIG(binds[bind])); 151 } 152 153 const char * 154 conv_sym_shndx(Half shndx, Conv_inv_buf_t *inv_buf) 155 { 156 switch (shndx) { 157 case SHN_UNDEF: 158 return (MSG_ORIG(MSG_SHN_UNDEF)); 159 case SHN_SUNW_IGNORE: 160 return (MSG_ORIG(MSG_SHN_SUNW_IGNORE)); 161 case SHN_ABS: 162 return (MSG_ORIG(MSG_SHN_ABS)); 163 case SHN_COMMON: 164 return (MSG_ORIG(MSG_SHN_COMMON)); 165 case SHN_AMD64_LCOMMON: 166 return (MSG_ORIG(MSG_SHN_AMD64_LCOMMON)); 167 case SHN_AFTER: 168 return (MSG_ORIG(MSG_SHN_AFTER)); 169 case SHN_BEFORE: 170 return (MSG_ORIG(MSG_SHN_BEFORE)); 171 case SHN_XINDEX: 172 return (MSG_ORIG(MSG_SHN_XINDEX)); 173 default: 174 return (conv_invalid_val(inv_buf, shndx, CONV_FMT_DECIMAL)); 175 } 176 } 177 178 const char * 179 conv_sym_value(Half mach, uchar_t type, Addr value, Conv_inv_buf_t *inv_buf) 180 { 181 if (((mach == EM_SPARC) || (mach == EM_SPARC32PLUS) || 182 (mach == EM_SPARCV9)) && (type == STT_SPARC_REGISTER)) 183 return (conv_sym_SPARC_value(value, 0, inv_buf)); 184 185 (void) snprintf(inv_buf->buf, sizeof (inv_buf->buf), 186 MSG_ORIG(MSG_SYM_FMT_VAL), EC_ADDR(value)); 187 return (inv_buf->buf); 188 } 189