xref: /illumos-gate/usr/src/cmd/sgs/libconv/common/cap.c (revision e9af4bc0b1cc30cea75d6ad4aa2fde97d985e9be)
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 routine for hardware capabilities types.
29  */
30 #include	<strings.h>
31 #include	<stdio.h>
32 #include	<elfcap.h>
33 #include	"cap_msg.h"
34 #include	"_conv.h"
35 
36 const conv_ds_t **
37 conv_cap_tag_strings(Conv_fmt_flags_t fmt_flags)
38 {
39 	static const Msg	tags_cf[] = {
40 		MSG_CA_SUNW_NULL_CF,	MSG_CA_SUNW_HW_1_CF,
41 		MSG_CA_SUNW_SF_1_CF
42 	};
43 	static const Msg	tags_nf[] = {
44 		MSG_CA_SUNW_NULL_NF,	MSG_CA_SUNW_HW_1_NF,
45 		MSG_CA_SUNW_SF_1_NF
46 	};
47 	static const conv_ds_msg_t ds_tags_cf = {
48 	    CONV_DS_MSG_INIT(ELFCLASSNONE, tags_cf) };
49 	static const conv_ds_msg_t ds_tags_nf = {
50 	    CONV_DS_MSG_INIT(ELFCLASSNONE, tags_nf) };
51 
52 	static const conv_ds_t *ds_cf[] = { CONV_DS_ADDR(ds_tags_cf), NULL };
53 	static const conv_ds_t *ds_nf[] = { CONV_DS_ADDR(ds_tags_nf), NULL };
54 
55 
56 	return ((CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_NF) ?
57 	    ds_nf : ds_cf);
58 }
59 
60 conv_iter_ret_t
61 conv_iter_cap_tags(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func,
62     void *uvalue)
63 {
64 	return (conv_iter_ds(ELFOSABI_NONE, EM_NONE,
65 	    conv_cap_tag_strings(fmt_flags), func, uvalue));
66 }
67 
68 /*
69  * Given an array of elfcap_desc_t, and a count, call the specified
70  * iteration for each value in the array.
71  */
72 static conv_iter_ret_t
73 conv_iter_elfcap(const elfcap_desc_t *cdp, uint_t cnum,
74     Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func, void *uvalue)
75 {
76 	const char	*str;
77 
78 	fmt_flags = CONV_TYPE_FMT_ALT(fmt_flags);
79 
80 	for (; cnum-- > 0; cdp++) {
81 		/*
82 		 * Skip "reserved" bits. These are unassigned bits in the
83 		 * middle of the assigned range.
84 		 */
85 		if (cdp->c_val == 0)
86 			continue;
87 
88 		switch (fmt_flags) {
89 		default:
90 			str = cdp->c_full.s_str;
91 			break;
92 		case CONV_FMT_ALT_CFNP:
93 			str = cdp->c_uc.s_str;
94 			break;
95 		case CONV_FMT_ALT_NF:
96 			str = cdp->c_lc.s_str;
97 			break;
98 		}
99 
100 		if ((* func)(str, cdp->c_val, uvalue) == CONV_ITER_DONE)
101 			return (CONV_ITER_DONE);
102 	}
103 
104 	return (CONV_ITER_CONT);
105 }
106 
107 /*
108  * Iterate the strings for CA_SUNW_HW1
109  */
110 conv_iter_ret_t
111 conv_iter_cap_val_hw1(Half mach, Conv_fmt_flags_t fmt_flags,
112     conv_iter_cb_t func, void *uvalue)
113 {
114 	if ((mach == EM_386) || (mach == EM_486) ||
115 	    (mach == EM_AMD64) || (mach == CONV_MACH_ALL))
116 		if (conv_iter_elfcap(elfcap_getdesc_hw1_386(),
117 		    ELFCAP_NUM_HW1_386, fmt_flags, func, uvalue) ==
118 		    CONV_ITER_DONE)
119 			return (CONV_ITER_DONE);
120 
121 	if ((mach == EM_SPARC) || (mach == EM_SPARC32PLUS) ||
122 	    (mach == EM_SPARCV9) || (mach == CONV_MACH_ALL))
123 		if (conv_iter_elfcap(elfcap_getdesc_hw1_sparc(),
124 		    ELFCAP_NUM_HW1_SPARC, fmt_flags, func, uvalue) ==
125 		    CONV_ITER_DONE)
126 			return (CONV_ITER_DONE);
127 
128 	return (CONV_ITER_CONT);
129 }
130 
131 /*
132  * Iterate the strings for CA_SUNW_SF1
133  */
134 conv_iter_ret_t
135 conv_iter_cap_val_sf1(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func,
136     void *uvalue)
137 {
138 	return (conv_iter_elfcap(elfcap_getdesc_sf1(), ELFCAP_NUM_SF1,
139 	    fmt_flags, func, uvalue));
140 }
141