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