cap.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 routine for hardware capabilities types.
30 */
31#include	<strings.h>
32#include	<stdio.h>
33#include	<sys/machelf.h>
34#include	<elfcap.h>
35#include	"cap_msg.h"
36#include	"_conv.h"
37
38static int
39conv_cap_1(Xword val, char *str, size_t len, Half mach,
40    int (*fptr)(uint64_t, char *, size_t, int, ushort_t))
41{
42	size_t	_len;
43
44	_len = sprintf(str, MSG_ORIG(MSG_GBL_OSQBRKT), EC_XWORD(val));
45
46	len -= _len;
47	str += _len;
48
49	if ((*fptr)(val, str, len, CAP_FMT_SNGSPACE, mach) != 0)
50		return (0);
51
52	_len = strlen(str);
53	if ((len - _len) >= MSG_GBL_CSQBRKT_SIZE) {
54		str += _len;
55		(void) strcpy(str, MSG_ORIG(MSG_GBL_CSQBRKT));
56	}
57	return (1);
58}
59
60const char *
61conv_cap_val_hw1(Xword val, Half mach, Conv_cap_val_hw1_buf_t *cap_val_hw1_buf)
62{
63	if (val == 0)
64		return (MSG_ORIG(MSG_GBL_ZERO));
65
66	if (conv_cap_1(val, cap_val_hw1_buf->buf, sizeof (cap_val_hw1_buf->buf),
67	    mach, hwcap_1_val2str) == 0)
68		return (conv_invalid_val(&cap_val_hw1_buf->inv_buf, val, 0));
69	return ((const char *)cap_val_hw1_buf->buf);
70}
71
72const char *
73conv_cap_val_sf1(Xword val, Half mach, Conv_cap_val_sf1_buf_t *cap_val_sf1_buf)
74{
75	if (val == 0)
76		return (MSG_ORIG(MSG_GBL_ZERO));
77
78	if (conv_cap_1(val, cap_val_sf1_buf->buf, sizeof (cap_val_sf1_buf->buf),
79	    mach, sfcap_1_val2str) == 0)
80		return (conv_invalid_val(&cap_val_sf1_buf->inv_buf, val, 0));
81	return ((const char *)cap_val_sf1_buf->buf);
82}
83
84const char *
85conv_cap_tag(Xword tag, Conv_inv_buf_t *inv_buf)
86{
87	static const Msg	tags[] = {
88		MSG_CA_SUNW_NULL,	MSG_CA_SUNW_HW_1,
89		MSG_CA_SUNW_SF_1
90	};
91
92	if (tag <= CA_SUNW_SF_1)
93		return (MSG_ORIG(tags[tag]));
94	else
95		return (conv_invalid_val(inv_buf, tag, 0));
96}
97
98const char *
99conv_cap_val(Xword tag, Xword val, Half mach, Conv_cap_val_buf_t *cap_val_buf)
100{
101	if (tag == CA_SUNW_HW_1)
102		return (conv_cap_val_hw1(val, mach,
103		    &cap_val_buf->cap_val_hw1_buf));
104	else if (tag == CA_SUNW_SF_1)
105		return (conv_cap_val_sf1(val, mach,
106		    &cap_val_buf->cap_val_sf1_buf));
107	else
108		return (conv_invalid_val(&cap_val_buf->inv_buf, val, 0));
109}
110