cap.c revision 2352:9cdfed81bb1c
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 2006 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
60/*
61 * Establish a buffer size based on the maximum number of hardware capabilities
62 * that exist.  See common/elfcap.
63 */
64#define	HW1SZ	200
65
66const char *
67conv_cap_val_hw1(Xword val, Half mach)
68{
69	static char	string[HW1SZ];
70
71	if (val == 0)
72		return (MSG_ORIG(MSG_GBL_ZERO));
73
74	if (conv_cap_1(val, string, HW1SZ, mach, hwcap_1_val2str) == 0)
75		return (conv_invalid_val(string, HW1SZ, val, 0));
76	return ((const char *)string);
77}
78
79/*
80 * Establish a buffer size based on the maximum number of software capabilities
81 * that exist.  See common/elfcap.
82 */
83#define	SF1SZ	50
84
85const char *
86conv_cap_val_sf1(Xword val, Half mach)
87{
88	static char	string[SF1SZ];
89
90	if (val == 0)
91		return (MSG_ORIG(MSG_GBL_ZERO));
92
93	if (conv_cap_1(val, string, SF1SZ, mach, sfcap_1_val2str) == 0)
94		return (conv_invalid_val(string, SF1SZ, val, 0));
95	return ((const char *)string);
96}
97
98const char *
99conv_cap_tag(Xword tag)
100{
101	static char		string[CONV_INV_STRSIZE];
102	static const Msg	tags[] = {
103		MSG_CA_SUNW_NULL,	MSG_CA_SUNW_HW_1,
104		MSG_CA_SUNW_SF_1
105	};
106
107	if (tag <= CA_SUNW_SF_1)
108		return (MSG_ORIG(tags[tag]));
109	else
110		return (conv_invalid_val(string, CONV_INV_STRSIZE, tag, 0));
111}
112
113const char *
114conv_cap_val(Xword tag, Xword val, Half mach)
115{
116	static char	string[CONV_INV_STRSIZE];
117
118	if (tag == CA_SUNW_HW_1)
119		return (conv_cap_val_hw1(val, mach));
120	else if (tag == CA_SUNW_SF_1)
121		return (conv_cap_val_sf1(val, mach));
122	else
123		return (conv_invalid_val(string, CONV_INV_STRSIZE, val, 0));
124}
125