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 2007 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 <sys/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[4] = { 42 'D', /* STV_DEFAULT */ 43 'I', /* STV_INTERNAL */ 44 'H', /* STV_HIDDEN */ 45 'P' /* STV_PROTECTED */ 46 }; 47 uint_t vis = ELF_ST_VISIBILITY(other); 48 uint_t ndx = 0; 49 50 inv_buf->buf[ndx++] = visibility[vis]; 51 52 /* 53 * If unknown bits are present in st_other - throw out a '?' 54 */ 55 if (other & ~MSK_SYM_VISIBILITY) 56 inv_buf->buf[ndx++] = '?'; 57 inv_buf->buf[ndx++] = '\0'; 58 59 return (inv_buf->buf); 60 } 61 62 const char * 63 conv_sym_other_vis(uchar_t value, Conv_fmt_flags_t fmt_flags, 64 Conv_inv_buf_t *inv_buf) 65 { 66 static const Msg vis[] = { 67 MSG_STV_DEFAULT, MSG_STV_INTERNAL, 68 MSG_STV_HIDDEN, MSG_STV_PROTECTED 69 }; 70 71 static const Msg vis_alt[] = { 72 MSG_STV_DEFAULT_ALT, MSG_STV_INTERNAL_ALT, 73 MSG_STV_HIDDEN_ALT, MSG_STV_PROTECTED_ALT 74 }; 75 76 if (value >= (sizeof (vis) / sizeof (vis[0]))) 77 return (conv_invalid_val(inv_buf, value, fmt_flags)); 78 79 /* If full ELF names are desired, use those strings */ 80 if (CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_FULLNAME) 81 return (MSG_ORIG(vis_alt[value])); 82 83 /* Default strings */ 84 return (MSG_ORIG(vis[value])); 85 } 86 87 const char * 88 conv_sym_info_type(Half mach, uchar_t type, Conv_fmt_flags_t fmt_flags, 89 Conv_inv_buf_t *inv_buf) 90 { 91 static const Msg types[] = { 92 MSG_STT_NOTYPE, MSG_STT_OBJECT, 93 MSG_STT_FUNC, MSG_STT_SECTION, 94 MSG_STT_FILE, MSG_STT_COMMON, 95 MSG_STT_TLS 96 }; 97 98 static const Msg types_alt[] = { 99 MSG_STT_NOTYPE_ALT, MSG_STT_OBJECT_ALT, 100 MSG_STT_FUNC_ALT, MSG_STT_SECTION_ALT, 101 MSG_STT_FILE_ALT, MSG_STT_COMMON_ALT, 102 MSG_STT_TLS_ALT 103 }; 104 105 if (type < STT_NUM) { 106 /* If full ELF names are desired, use those strings */ 107 if (CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_FULLNAME) 108 return (MSG_ORIG(types_alt[type])); 109 110 /* Default strings */ 111 return (MSG_ORIG(types[type])); 112 } else if (((mach == EM_SPARC) || (mach == EM_SPARC32PLUS) || 113 (mach == EM_SPARCV9)) && (type == STT_SPARC_REGISTER)) { 114 if (CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_FULLNAME) 115 return (MSG_ORIG(MSG_STT_SPARC_REGISTER_ALT)); 116 117 return (MSG_ORIG(MSG_STT_SPARC_REGISTER)); 118 } else { 119 return (conv_invalid_val(inv_buf, type, fmt_flags)); 120 } 121 } 122 123 const char * 124 conv_sym_info_bind(uchar_t bind, Conv_fmt_flags_t fmt_flags, 125 Conv_inv_buf_t *inv_buf) 126 { 127 static const Msg binds[] = { 128 MSG_STB_LOCAL, MSG_STB_GLOBAL, MSG_STB_WEAK 129 }; 130 131 static const Msg binds_alt[] = { 132 MSG_STB_LOCAL_ALT, MSG_STB_GLOBAL_ALT, MSG_STB_WEAK_ALT 133 }; 134 135 if (bind >= STB_NUM) 136 return (conv_invalid_val(inv_buf, bind, fmt_flags)); 137 138 /* If full ELF names are desired, use those strings */ 139 if (CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_FULLNAME) 140 return (MSG_ORIG(binds_alt[bind])); 141 142 /* Default strings */ 143 return (MSG_ORIG(binds[bind])); 144 } 145 146 const char * 147 conv_sym_shndx(Half shndx, Conv_inv_buf_t *inv_buf) 148 { 149 switch (shndx) { 150 case SHN_UNDEF: 151 return (MSG_ORIG(MSG_SHN_UNDEF)); 152 case SHN_SUNW_IGNORE: 153 return (MSG_ORIG(MSG_SHN_SUNW_IGNORE)); 154 case SHN_ABS: 155 return (MSG_ORIG(MSG_SHN_ABS)); 156 case SHN_COMMON: 157 return (MSG_ORIG(MSG_SHN_COMMON)); 158 case SHN_AMD64_LCOMMON: 159 return (MSG_ORIG(MSG_SHN_AMD64_LCOMMON)); 160 case SHN_AFTER: 161 return (MSG_ORIG(MSG_SHN_AFTER)); 162 case SHN_BEFORE: 163 return (MSG_ORIG(MSG_SHN_BEFORE)); 164 case SHN_XINDEX: 165 return (MSG_ORIG(MSG_SHN_XINDEX)); 166 default: 167 return (conv_invalid_val(inv_buf, shndx, CONV_FMT_DECIMAL)); 168 } 169 } 170 171 const char * 172 conv_sym_value(Half mach, uchar_t type, Addr value, Conv_inv_buf_t *inv_buf) 173 { 174 if (((mach == EM_SPARC) || (mach == EM_SPARC32PLUS) || 175 (mach == EM_SPARCV9)) && (type == STT_SPARC_REGISTER)) 176 return (conv_sym_SPARC_value(value, 0, inv_buf)); 177 178 (void) snprintf(inv_buf->buf, sizeof (inv_buf->buf), 179 MSG_ORIG(MSG_SYM_FMT_VAL), EC_ADDR(value)); 180 return (inv_buf->buf); 181 } 182