symbols.c revision 4734:a4708faa3e85
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
38const char *
39conv_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 unkown bits are present in stother - 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
62const char *
63conv_sym_info_type(Half mach, uchar_t type, int fmt_flags,
64    Conv_inv_buf_t *inv_buf)
65{
66	static const Msg	types[] = {
67		MSG_STT_NOTYPE,		MSG_STT_OBJECT,		MSG_STT_FUNC,
68		MSG_STT_SECTION,	MSG_STT_FILE,		MSG_STT_COMMON,
69		MSG_STT_TLS
70	};
71
72	if (type < STT_NUM) {
73		return (MSG_ORIG(types[type]));
74	} else if (((mach == EM_SPARC) || (mach == EM_SPARC32PLUS) ||
75	    (mach == EM_SPARCV9)) && (type == STT_SPARC_REGISTER)) {
76		return (MSG_ORIG(MSG_STT_REGISTER));
77	} else {
78		return (conv_invalid_val(inv_buf, type, fmt_flags));
79	}
80}
81
82const char *
83conv_sym_info_bind(uchar_t bind, int fmt_flags, Conv_inv_buf_t *inv_buf)
84{
85	static const Msg	binds[] = {
86		MSG_STB_LOCAL,		MSG_STB_GLOBAL,		MSG_STB_WEAK
87	};
88
89	if (bind >= STB_NUM)
90		return (conv_invalid_val(inv_buf, bind, fmt_flags));
91	else
92		return (MSG_ORIG(binds[bind]));
93}
94
95const char *
96conv_sym_shndx(Half shndx, Conv_inv_buf_t *inv_buf)
97{
98	switch (shndx) {
99	case SHN_UNDEF:
100		return (MSG_ORIG(MSG_SHN_UNDEF));
101	case SHN_SUNW_IGNORE:
102		return (MSG_ORIG(MSG_SHN_SUNW_IGNORE));
103	case SHN_ABS:
104		return (MSG_ORIG(MSG_SHN_ABS));
105	case SHN_COMMON:
106		return (MSG_ORIG(MSG_SHN_COMMON));
107	case SHN_AMD64_LCOMMON:
108		return (MSG_ORIG(MSG_SHN_AMD64_LCOMMON));
109	case SHN_AFTER:
110		return (MSG_ORIG(MSG_SHN_AFTER));
111	case SHN_BEFORE:
112		return (MSG_ORIG(MSG_SHN_BEFORE));
113	case SHN_XINDEX:
114		return (MSG_ORIG(MSG_SHN_XINDEX));
115	default:
116		return (conv_invalid_val(inv_buf, shndx, CONV_FMT_DECIMAL));
117	}
118}
119
120const char *
121conv_sym_value(Half mach, uchar_t type, Addr value, Conv_inv_buf_t *inv_buf)
122{
123	if (((mach == EM_SPARC) || (mach == EM_SPARC32PLUS) ||
124	    (mach == EM_SPARCV9)) && (type == STT_SPARC_REGISTER))
125		return (conv_sym_SPARC_value(value, 0, inv_buf));
126
127	(void) snprintf(inv_buf->buf, sizeof (inv_buf->buf),
128	    MSG_ORIG(MSG_SYM_FMT_VAL), EC_ADDR(value));
129	return (inv_buf->buf);
130}
131