xref: /titanic_44/usr/src/cmd/sgs/libconv/common/symbols.c (revision 2e107de79998f3036decec2454002940afb9a6ff)
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