xref: /illumos-gate/usr/src/cmd/sgs/libconv/common/symbols.c (revision ba2be53024c0b999e74ba9adcd7d80fec5df8c57)
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