xref: /illumos-gate/usr/src/common/elfcap/elfcap.c (revision 56726c7e)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51820c2cdShyw  * Common Development and Distribution License (the "License").
61820c2cdShyw  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
21ae115bc7Smrj 
227c478bd9Sstevel@tonic-gate /*
237af88ac7SKuriakose Kuruvilla  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
24e4f6ce70SRobert Mustacchi  * Copyright 2019, Joyent, Inc.
25*56726c7eSRobert Mustacchi  * Copyright 2022 Oxide Computer Company
267c478bd9Sstevel@tonic-gate  */
27ae115bc7Smrj 
287c478bd9Sstevel@tonic-gate /* LINTLIBRARY */
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate /*
317c478bd9Sstevel@tonic-gate  * String conversion routine for hardware capabilities types.
327c478bd9Sstevel@tonic-gate  */
337c478bd9Sstevel@tonic-gate #include	<strings.h>
347c478bd9Sstevel@tonic-gate #include	<stdio.h>
357c478bd9Sstevel@tonic-gate #include	<ctype.h>
367c478bd9Sstevel@tonic-gate #include	<sys/machelf.h>
377c478bd9Sstevel@tonic-gate #include	<sys/elf.h>
387c478bd9Sstevel@tonic-gate #include	<sys/auxv_SPARC.h>
397c478bd9Sstevel@tonic-gate #include	<sys/auxv_386.h>
407c478bd9Sstevel@tonic-gate #include	<elfcap.h>
417c478bd9Sstevel@tonic-gate 
427c478bd9Sstevel@tonic-gate /*
4399f63845Sab  * Given a literal string, generate an initialization for an
4499f63845Sab  * elfcap_str_t value.
457c478bd9Sstevel@tonic-gate  */
4699f63845Sab #define	STRDESC(_str) { _str, sizeof (_str) - 1 }
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate /*
4999f63845Sab  * The items in the elfcap_desc_t arrays are required to be
5099f63845Sab  * ordered so that the array index is related to the
5199f63845Sab  * c_val field as:
5299f63845Sab  *
5399f63845Sab  *	array[ndx].c_val = 2^ndx
5499f63845Sab  *
5599f63845Sab  * meaning that
5699f63845Sab  *
5799f63845Sab  *	array[0].c_val = 2^0 = 1
5899f63845Sab  *	array[1].c_val = 2^1 = 2
5999f63845Sab  *	array[2].c_val = 2^2 = 4
6099f63845Sab  *	.
6199f63845Sab  *	.
6299f63845Sab  *	.
6399f63845Sab  *
6499f63845Sab  * Since 0 is not a valid value for the c_val field, we use it to
6599f63845Sab  * mark an array entry that is a placeholder. This can happen if there
6699f63845Sab  * is a hole in the assigned bits.
677c478bd9Sstevel@tonic-gate  *
6899f63845Sab  * The RESERVED_ELFCAP_DESC macro is used to reserve such holes.
697c478bd9Sstevel@tonic-gate  */
7099f63845Sab #define	RESERVED_ELFCAP_DESC { 0, { NULL, 0 }, { NULL, 0 }, { NULL, 0 } }
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate /*
7399f63845Sab  * Define separators for output string processing. This must be kept in
74*56726c7eSRobert Mustacchi  * sync with the elfcap_fmt_t values in elfcap.h. If something is added here
75*56726c7eSRobert Mustacchi  * that is longer than ELFCAP_FMT_PIPSPACE, please update elfcap_chk.c.
767c478bd9Sstevel@tonic-gate  */
7799f63845Sab static const elfcap_str_t format[] = {
7899f63845Sab 	STRDESC(" "),			/* ELFCAP_FMT_SNGSPACE */
7999f63845Sab 	STRDESC("  "),			/* ELFCAP_FMT_DBLSPACE */
8099f63845Sab 	STRDESC(" | ")			/* ELFCAP_FMT_PIPSPACE */
817c478bd9Sstevel@tonic-gate };
8299f63845Sab #define	FORMAT_NELTS	(sizeof (format) / sizeof (format[0]))
8399f63845Sab 
8499f63845Sab 
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate /*
8799f63845Sab  * Define all known software capabilities in all the supported styles.
8899f63845Sab  * Order the capabilities by their numeric value. See SF1_SUNW_
8999f63845Sab  * values in sys/elf.h.
907c478bd9Sstevel@tonic-gate  */
9199f63845Sab static const elfcap_desc_t sf1[ELFCAP_NUM_SF1] = {
9299f63845Sab 	{						/* 0x00000001 */
9399f63845Sab 		SF1_SUNW_FPKNWN, STRDESC("SF1_SUNW_FPKNWN"),
9499f63845Sab 		STRDESC("FPKNWN"), STRDESC("fpknwn")
9599f63845Sab 	},
9699f63845Sab 	{						/* 0x00000002 */
9799f63845Sab 		SF1_SUNW_FPUSED, STRDESC("SF1_SUNW_FPUSED"),
9899f63845Sab 		STRDESC("FPUSED"), STRDESC("fpused"),
99bebb829dSRod Evans 	},
100bebb829dSRod Evans 	{						/* 0x00000004 */
101bebb829dSRod Evans 		SF1_SUNW_ADDR32, STRDESC("SF1_SUNW_ADDR32"),
102bebb829dSRod Evans 		STRDESC("ADDR32"), STRDESC("addr32"),
10399f63845Sab 	}
10499f63845Sab };
10599f63845Sab 
10699f63845Sab 
1077c478bd9Sstevel@tonic-gate 
1087c478bd9Sstevel@tonic-gate /*
1097c478bd9Sstevel@tonic-gate  * Order the SPARC hardware capabilities to match their numeric value.  See
1107c478bd9Sstevel@tonic-gate  * AV_SPARC_ values in sys/auxv_SPARC.h.
1117c478bd9Sstevel@tonic-gate  */
11299f63845Sab static const elfcap_desc_t hw1_sparc[ELFCAP_NUM_HW1_SPARC] = {
11399f63845Sab 	{						/* 0x00000001 */
11499f63845Sab 		AV_SPARC_MUL32, STRDESC("AV_SPARC_MUL32"),
11599f63845Sab 		STRDESC("MUL32"), STRDESC("mul32"),
11699f63845Sab 	},
11799f63845Sab 	{						/* 0x00000002 */
11899f63845Sab 		AV_SPARC_DIV32, STRDESC("AV_SPARC_DIV32"),
11999f63845Sab 		STRDESC("DIV32"), STRDESC("div32"),
12099f63845Sab 	},
12199f63845Sab 	{						/* 0x00000004 */
12299f63845Sab 		AV_SPARC_FSMULD, STRDESC("AV_SPARC_FSMULD"),
12399f63845Sab 		STRDESC("FSMULD"), STRDESC("fsmuld"),
12499f63845Sab 	},
12599f63845Sab 	{						/* 0x00000008 */
12699f63845Sab 		AV_SPARC_V8PLUS, STRDESC("AV_SPARC_V8PLUS"),
12799f63845Sab 		STRDESC("V8PLUS"), STRDESC("v8plus"),
12899f63845Sab 	},
12999f63845Sab 	{						/* 0x00000010 */
13099f63845Sab 		AV_SPARC_POPC, STRDESC("AV_SPARC_POPC"),
13199f63845Sab 		STRDESC("POPC"), STRDESC("popc"),
13299f63845Sab 	},
13399f63845Sab 	{						/* 0x00000020 */
13499f63845Sab 		AV_SPARC_VIS, STRDESC("AV_SPARC_VIS"),
13599f63845Sab 		STRDESC("VIS"), STRDESC("vis"),
13699f63845Sab 	},
13799f63845Sab 	{						/* 0x00000040 */
13899f63845Sab 		AV_SPARC_VIS2, STRDESC("AV_SPARC_VIS2"),
13999f63845Sab 		STRDESC("VIS2"), STRDESC("vis2"),
14099f63845Sab 	},
14199f63845Sab 	{						/* 0x00000080 */
14299f63845Sab 		AV_SPARC_ASI_BLK_INIT, STRDESC("AV_SPARC_ASI_BLK_INIT"),
14399f63845Sab 		STRDESC("ASI_BLK_INIT"), STRDESC("asi_blk_init"),
14499f63845Sab 	},
14599f63845Sab 	{						/* 0x00000100 */
14699f63845Sab 		AV_SPARC_FMAF, STRDESC("AV_SPARC_FMAF"),
14799f63845Sab 		STRDESC("FMAF"), STRDESC("fmaf"),
14899f63845Sab 	},
1499d0d62adSJason Beloro 	RESERVED_ELFCAP_DESC,				/* 0x00000200 */
1502f0fcb93SJason Beloro 	{						/* 0x00000400 */
1512f0fcb93SJason Beloro 		AV_SPARC_VIS3, STRDESC("AV_SPARC_VIS3"),
1522f0fcb93SJason Beloro 		STRDESC("VIS3"), STRDESC("vis3"),
1532f0fcb93SJason Beloro 	},
1542f0fcb93SJason Beloro 	{						/* 0x00000800 */
1552f0fcb93SJason Beloro 		AV_SPARC_HPC, STRDESC("AV_SPARC_HPC"),
1562f0fcb93SJason Beloro 		STRDESC("HPC"), STRDESC("hpc"),
1572f0fcb93SJason Beloro 	},
1582f0fcb93SJason Beloro 	{						/* 0x00001000 */
1592f0fcb93SJason Beloro 		AV_SPARC_RANDOM, STRDESC("AV_SPARC_RANDOM"),
1602f0fcb93SJason Beloro 		STRDESC("RANDOM"), STRDESC("random"),
1612f0fcb93SJason Beloro 	},
1622f0fcb93SJason Beloro 	{						/* 0x00002000 */
1632f0fcb93SJason Beloro 		AV_SPARC_TRANS, STRDESC("AV_SPARC_TRANS"),
1642f0fcb93SJason Beloro 		STRDESC("TRANS"), STRDESC("trans"),
1652f0fcb93SJason Beloro 	},
16699f63845Sab 	{						/* 0x00004000 */
16799f63845Sab 		AV_SPARC_FJFMAU, STRDESC("AV_SPARC_FJFMAU"),
16899f63845Sab 		STRDESC("FJFMAU"), STRDESC("fjfmau"),
16999f63845Sab 	},
17099f63845Sab 	{						/* 0x00008000 */
17199f63845Sab 		AV_SPARC_IMA, STRDESC("AV_SPARC_IMA"),
17299f63845Sab 		STRDESC("IMA"), STRDESC("ima"),
173b1593d50SJason Beloro 	},
174b1593d50SJason Beloro 	{						/* 0x00010000 */
175b1593d50SJason Beloro 		AV_SPARC_ASI_CACHE_SPARING,
176b1593d50SJason Beloro 		STRDESC("AV_SPARC_ASI_CACHE_SPARING"),
177b1593d50SJason Beloro 		STRDESC("CSPARE"), STRDESC("cspare"),
1781ba081eeSToomas Soome 	},
1791ba081eeSToomas Soome 	{						/* 0x00020000 */
1801ba081eeSToomas Soome 		AV_SPARC_PAUSE,
1811ba081eeSToomas Soome 		STRDESC("AV_SPARC_PAUSE"),
1821ba081eeSToomas Soome 		STRDESC("PAUSE"), STRDESC("pause"),
1831ba081eeSToomas Soome 	},
1841ba081eeSToomas Soome 	{						/* 0x00040000 */
1851ba081eeSToomas Soome 		AV_SPARC_CBCOND,
1861ba081eeSToomas Soome 		STRDESC("AV_SPARC_CBCOND"),
1871ba081eeSToomas Soome 		STRDESC("CBCOND"), STRDESC("cbcond"),
1881ba081eeSToomas Soome 	},
1891ba081eeSToomas Soome 	{						/* 0x00080000 */
1901ba081eeSToomas Soome 		AV_SPARC_AES,
1911ba081eeSToomas Soome 		STRDESC("AV_SPARC_AES"),
1921ba081eeSToomas Soome 		STRDESC("AES"), STRDESC("aes"),
1931ba081eeSToomas Soome 	},
1941ba081eeSToomas Soome 	{						/* 0x00100000 */
1951ba081eeSToomas Soome 		AV_SPARC_DES,
1961ba081eeSToomas Soome 		STRDESC("AV_SPARC_DES"),
1971ba081eeSToomas Soome 		STRDESC("DES"), STRDESC("des"),
1981ba081eeSToomas Soome 	},
1991ba081eeSToomas Soome 	{						/* 0x00200000 */
2001ba081eeSToomas Soome 		AV_SPARC_KASUMI,
2011ba081eeSToomas Soome 		STRDESC("AV_SPARC_KASUMI"),
2021ba081eeSToomas Soome 		STRDESC("KASUMI"), STRDESC("kasumi"),
2031ba081eeSToomas Soome 	},
2041ba081eeSToomas Soome 	{						/* 0x00400000 */
2051ba081eeSToomas Soome 		AV_SPARC_CAMELLIA,
2061ba081eeSToomas Soome 		STRDESC("AV_SPARC_CAMELLIA"),
2071ba081eeSToomas Soome 		STRDESC("CAMELLIA"), STRDESC("camellia"),
2081ba081eeSToomas Soome 	},
2091ba081eeSToomas Soome 	{						/* 0x00800000 */
2101ba081eeSToomas Soome 		AV_SPARC_MD5,
2111ba081eeSToomas Soome 		STRDESC("AV_SPARC_MD5"),
2121ba081eeSToomas Soome 		STRDESC("MD5"), STRDESC("md5"),
2131ba081eeSToomas Soome 	},
2141ba081eeSToomas Soome 	{						/* 0x01000000 */
2151ba081eeSToomas Soome 		AV_SPARC_SHA1,
2161ba081eeSToomas Soome 		STRDESC("AV_SPARC_SHA1"),
2171ba081eeSToomas Soome 		STRDESC("SHA1"), STRDESC("sha1"),
2181ba081eeSToomas Soome 	},
2191ba081eeSToomas Soome 	{						/* 0x02000000 */
2201ba081eeSToomas Soome 		AV_SPARC_SHA256,
2211ba081eeSToomas Soome 		STRDESC("AV_SPARC_SHA256"),
2221ba081eeSToomas Soome 		STRDESC("SHA256"), STRDESC("sha256"),
2231ba081eeSToomas Soome 	},
2241ba081eeSToomas Soome 	{						/* 0x04000000 */
2251ba081eeSToomas Soome 		AV_SPARC_SHA512,
2261ba081eeSToomas Soome 		STRDESC("AV_SPARC_SHA512"),
2271ba081eeSToomas Soome 		STRDESC("SHA512"), STRDESC("sha512"),
2281ba081eeSToomas Soome 	},
2291ba081eeSToomas Soome 	{						/* 0x08000000 */
2301ba081eeSToomas Soome 		AV_SPARC_MPMUL,
2311ba081eeSToomas Soome 		STRDESC("AV_SPARC_MPMUL"),
2321ba081eeSToomas Soome 		STRDESC("MPMUL"), STRDESC("mpmul"),
2331ba081eeSToomas Soome 	},
2341ba081eeSToomas Soome 	{						/* 0x10000000 */
2351ba081eeSToomas Soome 		AV_SPARC_MONT,
2361ba081eeSToomas Soome 		STRDESC("AV_SPARC_MONT"),
2371ba081eeSToomas Soome 		STRDESC("MONT"), STRDESC("mont"),
2381ba081eeSToomas Soome 	},
2391ba081eeSToomas Soome 	{						/* 0x20000000 */
2401ba081eeSToomas Soome 		AV_SPARC_CRC32C,
2411ba081eeSToomas Soome 		STRDESC("AV_SPARC_CRC32C"),
2421ba081eeSToomas Soome 		STRDESC("CRC32C"), STRDESC("crc32c"),
24399f63845Sab 	}
2447c478bd9Sstevel@tonic-gate };
2457c478bd9Sstevel@tonic-gate 
24699f63845Sab 
2477c478bd9Sstevel@tonic-gate 
2487c478bd9Sstevel@tonic-gate /*
2497c478bd9Sstevel@tonic-gate  * Order the Intel hardware capabilities to match their numeric value.  See
2507c478bd9Sstevel@tonic-gate  * AV_386_ values in sys/auxv_386.h.
2517c478bd9Sstevel@tonic-gate  */
25299f63845Sab static const elfcap_desc_t hw1_386[ELFCAP_NUM_HW1_386] = {
25399f63845Sab 	{						/* 0x00000001 */
25499f63845Sab 		AV_386_FPU, STRDESC("AV_386_FPU"),
25599f63845Sab 		STRDESC("FPU"), STRDESC("fpu"),
25699f63845Sab 	},
25799f63845Sab 	{						/* 0x00000002 */
25899f63845Sab 		AV_386_TSC, STRDESC("AV_386_TSC"),
25999f63845Sab 		STRDESC("TSC"), STRDESC("tsc"),
26099f63845Sab 	},
26199f63845Sab 	{						/* 0x00000004 */
26299f63845Sab 		AV_386_CX8, STRDESC("AV_386_CX8"),
26399f63845Sab 		STRDESC("CX8"), STRDESC("cx8"),
26499f63845Sab 	},
26599f63845Sab 	{						/* 0x00000008 */
26699f63845Sab 		AV_386_SEP, STRDESC("AV_386_SEP"),
26799f63845Sab 		STRDESC("SEP"), STRDESC("sep"),
26899f63845Sab 	},
26999f63845Sab 	{						/* 0x00000010 */
27099f63845Sab 		AV_386_AMD_SYSC, STRDESC("AV_386_AMD_SYSC"),
27199f63845Sab 		STRDESC("AMD_SYSC"), STRDESC("amd_sysc"),
27299f63845Sab 	},
27399f63845Sab 	{						/* 0x00000020 */
27499f63845Sab 		AV_386_CMOV, STRDESC("AV_386_CMOV"),
27599f63845Sab 		STRDESC("CMOV"), STRDESC("cmov"),
27699f63845Sab 	},
27799f63845Sab 	{						/* 0x00000040 */
27899f63845Sab 		AV_386_MMX, STRDESC("AV_386_MMX"),
27999f63845Sab 		STRDESC("MMX"), STRDESC("mmx"),
28099f63845Sab 	},
28199f63845Sab 	{						/* 0x00000080 */
28299f63845Sab 		AV_386_AMD_MMX, STRDESC("AV_386_AMD_MMX"),
28399f63845Sab 		STRDESC("AMD_MMX"), STRDESC("amd_mmx"),
28499f63845Sab 	},
28599f63845Sab 	{						/* 0x00000100 */
28699f63845Sab 		AV_386_AMD_3DNow, STRDESC("AV_386_AMD_3DNow"),
28799f63845Sab 		STRDESC("AMD_3DNow"), STRDESC("amd_3dnow"),
28899f63845Sab 	},
28999f63845Sab 	{						/* 0x00000200 */
29099f63845Sab 		AV_386_AMD_3DNowx, STRDESC("AV_386_AMD_3DNowx"),
29199f63845Sab 		STRDESC("AMD_3DNowx"), STRDESC("amd_3dnowx"),
29299f63845Sab 	},
29399f63845Sab 	{						/* 0x00000400 */
29499f63845Sab 		AV_386_FXSR, STRDESC("AV_386_FXSR"),
29599f63845Sab 		STRDESC("FXSR"), STRDESC("fxsr"),
29699f63845Sab 	},
29799f63845Sab 	{						/* 0x00000800 */
29899f63845Sab 		AV_386_SSE, STRDESC("AV_386_SSE"),
29999f63845Sab 		STRDESC("SSE"), STRDESC("sse"),
30099f63845Sab 	},
30199f63845Sab 	{						/* 0x00001000 */
30299f63845Sab 		AV_386_SSE2, STRDESC("AV_386_SSE2"),
30399f63845Sab 		STRDESC("SSE2"), STRDESC("sse2"),
30499f63845Sab 	},
3054e12d685SRod Evans 	/* 0x02000 withdrawn - do not assign */
30699f63845Sab 	{						/* 0x00004000 */
30799f63845Sab 		AV_386_SSE3, STRDESC("AV_386_SSE3"),
30899f63845Sab 		STRDESC("SSE3"), STRDESC("sse3"),
30999f63845Sab 	},
3104e12d685SRod Evans 	/* 0x08000 withdrawn - do not assign */
31199f63845Sab 	{						/* 0x00010000 */
31299f63845Sab 		AV_386_CX16, STRDESC("AV_386_CX16"),
31399f63845Sab 		STRDESC("CX16"), STRDESC("cx16"),
31499f63845Sab 	},
31599f63845Sab 	{						/* 0x00020000 */
31699f63845Sab 		AV_386_AHF, STRDESC("AV_386_AHF"),
31799f63845Sab 		STRDESC("AHF"), STRDESC("ahf"),
31899f63845Sab 	},
31999f63845Sab 	{						/* 0x00040000 */
32099f63845Sab 		AV_386_TSCP, STRDESC("AV_386_TSCP"),
32199f63845Sab 		STRDESC("TSCP"), STRDESC("tscp"),
32299f63845Sab 	},
32399f63845Sab 	{						/* 0x00080000 */
32499f63845Sab 		AV_386_AMD_SSE4A, STRDESC("AV_386_AMD_SSE4A"),
32599f63845Sab 		STRDESC("AMD_SSE4A"), STRDESC("amd_sse4a"),
32699f63845Sab 	},
32799f63845Sab 	{						/* 0x00100000 */
32899f63845Sab 		AV_386_POPCNT, STRDESC("AV_386_POPCNT"),
32999f63845Sab 		STRDESC("POPCNT"), STRDESC("popcnt"),
33099f63845Sab 	},
33199f63845Sab 	{						/* 0x00200000 */
33299f63845Sab 		AV_386_AMD_LZCNT, STRDESC("AV_386_AMD_LZCNT"),
33399f63845Sab 		STRDESC("AMD_LZCNT"), STRDESC("amd_lzcnt"),
33499f63845Sab 	},
33599f63845Sab 	{						/* 0x00400000 */
33699f63845Sab 		AV_386_SSSE3, STRDESC("AV_386_SSSE3"),
33799f63845Sab 		STRDESC("SSSE3"), STRDESC("ssse3"),
33899f63845Sab 	},
33999f63845Sab 	{						/* 0x00800000 */
34099f63845Sab 		AV_386_SSE4_1, STRDESC("AV_386_SSE4_1"),
34199f63845Sab 		STRDESC("SSE4.1"), STRDESC("sse4.1"),
34299f63845Sab 	},
34399f63845Sab 	{						/* 0x01000000 */
34499f63845Sab 		AV_386_SSE4_2, STRDESC("AV_386_SSE4_2"),
34599f63845Sab 		STRDESC("SSE4.2"), STRDESC("sse4.2"),
3465087e485SKrishnendu Sadhukhan - Sun Microsystems 	},
3475087e485SKrishnendu Sadhukhan - Sun Microsystems 	{						/* 0x02000000 */
3485087e485SKrishnendu Sadhukhan - Sun Microsystems 		AV_386_MOVBE, STRDESC("AV_386_MOVBE"),
3495087e485SKrishnendu Sadhukhan - Sun Microsystems 		STRDESC("MOVBE"), STRDESC("movbe"),
350a50a8b93SKuriakose Kuruvilla 	},
351a50a8b93SKuriakose Kuruvilla 	{						/* 0x04000000 */
352a50a8b93SKuriakose Kuruvilla 		AV_386_AES, STRDESC("AV_386_AES"),
353a50a8b93SKuriakose Kuruvilla 		STRDESC("AES"), STRDESC("aes"),
354a50a8b93SKuriakose Kuruvilla 	},
355a50a8b93SKuriakose Kuruvilla 	{						/* 0x08000000 */
356a50a8b93SKuriakose Kuruvilla 		AV_386_PCLMULQDQ, STRDESC("AV_386_PCLMULQDQ"),
357a50a8b93SKuriakose Kuruvilla 		STRDESC("PCLMULQDQ"), STRDESC("pclmulqdq"),
3587af88ac7SKuriakose Kuruvilla 	},
3597af88ac7SKuriakose Kuruvilla 	{						/* 0x10000000 */
3607af88ac7SKuriakose Kuruvilla 		AV_386_XSAVE, STRDESC("AV_386_XSAVE"),
3617af88ac7SKuriakose Kuruvilla 		STRDESC("XSAVE"), STRDESC("xsave"),
3627af88ac7SKuriakose Kuruvilla 	},
3637af88ac7SKuriakose Kuruvilla 	{						/* 0x20000000 */
3647af88ac7SKuriakose Kuruvilla 		AV_386_AVX, STRDESC("AV_386_AVX"),
3657af88ac7SKuriakose Kuruvilla 		STRDESC("AVX"), STRDESC("avx"),
366faa20166SBryan Cantrill 	},
367faa20166SBryan Cantrill 	{						/* 0x40000000 */
368faa20166SBryan Cantrill 		AV_386_VMX, STRDESC("AV_386_VMX"),
369faa20166SBryan Cantrill 		STRDESC("VMX"), STRDESC("vmx"),
370faa20166SBryan Cantrill 	},
371faa20166SBryan Cantrill 	{						/* 0x80000000 */
372faa20166SBryan Cantrill 		AV_386_AMD_SVM, STRDESC("AV_386_AMD_SVM"),
373faa20166SBryan Cantrill 		STRDESC("AMD_SVM"), STRDESC("amd_svm"),
37499f63845Sab 	}
3757c478bd9Sstevel@tonic-gate };
3767c478bd9Sstevel@tonic-gate 
377ebb8ac07SRobert Mustacchi static const elfcap_desc_t hw2_386[ELFCAP_NUM_HW2_386] = {
378ebb8ac07SRobert Mustacchi 	{						/* 0x00000001 */
379ebb8ac07SRobert Mustacchi 		AV_386_2_F16C, STRDESC("AV_386_2_F16C"),
380ebb8ac07SRobert Mustacchi 		STRDESC("F16C"), STRDESC("f16c"),
381ebb8ac07SRobert Mustacchi 	},
382ebb8ac07SRobert Mustacchi 	{						/* 0x00000002 */
383ebb8ac07SRobert Mustacchi 		AV_386_2_RDRAND, STRDESC("AV_386_2_RDRAND"),
384ebb8ac07SRobert Mustacchi 		STRDESC("RDRAND"), STRDESC("rdrand"),
385245ac945SRobert Mustacchi 	},
386245ac945SRobert Mustacchi 	{						/* 0x00000004 */
387245ac945SRobert Mustacchi 		AV_386_2_BMI1, STRDESC("AV_386_2_BMI1"),
388245ac945SRobert Mustacchi 		STRDESC("BMI1"), STRDESC("bmi1"),
389245ac945SRobert Mustacchi 	},
390245ac945SRobert Mustacchi 	{						/* 0x00000008 */
391245ac945SRobert Mustacchi 		AV_386_2_BMI2, STRDESC("AV_386_2_BMI2"),
392245ac945SRobert Mustacchi 		STRDESC("BMI2"), STRDESC("bmi2"),
393245ac945SRobert Mustacchi 	},
394245ac945SRobert Mustacchi 	{						/* 0x00000010 */
395245ac945SRobert Mustacchi 		AV_386_2_FMA, STRDESC("AV_386_2_FMA"),
396245ac945SRobert Mustacchi 		STRDESC("FMA"), STRDESC("fma"),
397245ac945SRobert Mustacchi 	},
398245ac945SRobert Mustacchi 	{						/* 0x00000020 */
399245ac945SRobert Mustacchi 		AV_386_2_AVX2, STRDESC("AV_386_2_AVX2"),
400245ac945SRobert Mustacchi 		STRDESC("AVX2"), STRDESC("avx2"),
401245ac945SRobert Mustacchi 	},
4028889c875SRobert Mustacchi 	{						/* 0x00000040 */
4038889c875SRobert Mustacchi 		AV_386_2_ADX, STRDESC("AV_386_2_ADX"),
4048889c875SRobert Mustacchi 		STRDESC("ADX"), STRDESC("adx"),
4058889c875SRobert Mustacchi 	},
4068889c875SRobert Mustacchi 	{						/* 0x00000080 */
4078889c875SRobert Mustacchi 		AV_386_2_RDSEED, STRDESC("AV_386_2_RDSEED"),
4088889c875SRobert Mustacchi 		STRDESC("RDSEED"), STRDESC("rdseed"),
409088d69f8SJerry Jelinek 	},
410088d69f8SJerry Jelinek 	{						/* 0x00000100 */
411088d69f8SJerry Jelinek 		AV_386_2_AVX512F, STRDESC("AV_386_2_AVX512F"),
412088d69f8SJerry Jelinek 		STRDESC("AVX512F"), STRDESC("avx512f"),
413088d69f8SJerry Jelinek 	},
414088d69f8SJerry Jelinek 	{						/* 0x00000200 */
415088d69f8SJerry Jelinek 		AV_386_2_AVX512DQ, STRDESC("AV_386_2_AVX512DQ"),
416088d69f8SJerry Jelinek 		STRDESC("AVX512DQ"), STRDESC("avx512dq"),
417088d69f8SJerry Jelinek 	},
418088d69f8SJerry Jelinek 	{						/* 0x00000400 */
419088d69f8SJerry Jelinek 		AV_386_2_AVX512IFMA, STRDESC("AV_386_2_AVX512IFMA"),
420088d69f8SJerry Jelinek 		STRDESC("AVX512IFMA"), STRDESC("avx512ifma"),
421088d69f8SJerry Jelinek 	},
422088d69f8SJerry Jelinek 	{						/* 0x00000800 */
423088d69f8SJerry Jelinek 		AV_386_2_AVX512PF, STRDESC("AV_386_2_AVX512PF"),
424088d69f8SJerry Jelinek 		STRDESC("AVX512PF"), STRDESC("avx512pf"),
425088d69f8SJerry Jelinek 	},
426088d69f8SJerry Jelinek 	{						/* 0x00001000 */
427088d69f8SJerry Jelinek 		AV_386_2_AVX512ER, STRDESC("AV_386_2_AVX512ER"),
428088d69f8SJerry Jelinek 		STRDESC("AVX512ER"), STRDESC("avx512er"),
429088d69f8SJerry Jelinek 	},
430088d69f8SJerry Jelinek 	{						/* 0x00002000 */
431088d69f8SJerry Jelinek 		AV_386_2_AVX512CD, STRDESC("AV_386_2_AVX512CD"),
432088d69f8SJerry Jelinek 		STRDESC("AVX512CD"), STRDESC("avx512cd"),
433088d69f8SJerry Jelinek 	},
434088d69f8SJerry Jelinek 	{						/* 0x00004000 */
435088d69f8SJerry Jelinek 		AV_386_2_AVX512BW, STRDESC("AV_386_2_AVX512BW"),
436088d69f8SJerry Jelinek 		STRDESC("AVX512BW"), STRDESC("avx512bw"),
437088d69f8SJerry Jelinek 	},
438088d69f8SJerry Jelinek 	{						/* 0x00008000 */
439088d69f8SJerry Jelinek 		AV_386_2_AVX512VL, STRDESC("AV_386_2_AVX512VL"),
440088d69f8SJerry Jelinek 		STRDESC("AVX512VL"), STRDESC("avx512vl"),
441088d69f8SJerry Jelinek 	},
442088d69f8SJerry Jelinek 	{						/* 0x00010000 */
443088d69f8SJerry Jelinek 		AV_386_2_AVX512VBMI, STRDESC("AV_386_2_AVX512VBMI"),
444088d69f8SJerry Jelinek 		STRDESC("AVX512VBMI"), STRDESC("avx512vbmi"),
445088d69f8SJerry Jelinek 	},
446088d69f8SJerry Jelinek 	{						/* 0x00020000 */
447161294feSRobert Mustacchi 		AV_386_2_AVX512VPOPCDQ, STRDESC("AV_386_2_AVX512_VPOPCDQ"),
448161294feSRobert Mustacchi 		STRDESC("AVX512_VPOPCDQ"), STRDESC("avx512_vpopcntdq"),
449088d69f8SJerry Jelinek 	},
450088d69f8SJerry Jelinek 	{						/* 0x00040000 */
451088d69f8SJerry Jelinek 		AV_386_2_AVX512_4NNIW, STRDESC("AV_386_2_AVX512_4NNIW"),
452088d69f8SJerry Jelinek 		STRDESC("AVX512_4NNIW"), STRDESC("avx512_4nniw"),
453088d69f8SJerry Jelinek 	},
454088d69f8SJerry Jelinek 	{						/* 0x00080000 */
455088d69f8SJerry Jelinek 		AV_386_2_AVX512_4FMAPS, STRDESC("AV_386_2_AVX512_4FMAPS"),
456088d69f8SJerry Jelinek 		STRDESC("AVX512_4FMAPS"), STRDESC("avx512_4fmaps"),
457088d69f8SJerry Jelinek 	},
458008b34beSRobert Mustacchi 	{						/* 0x00100000 */
459008b34beSRobert Mustacchi 		AV_386_2_SHA, STRDESC("AV_386_2_SHA"),
460008b34beSRobert Mustacchi 		STRDESC("SHA"), STRDESC("sha"),
461cff040f3SRobert Mustacchi 	},
462cff040f3SRobert Mustacchi 	{						/* 0x00200000 */
463cff040f3SRobert Mustacchi 		AV_386_2_FSGSBASE, STRDESC("AV_386_2_FSGSBASE"),
464cff040f3SRobert Mustacchi 		STRDESC("FSGSBASE"), STRDESC("fsgsbase")
465cff040f3SRobert Mustacchi 	},
466cff040f3SRobert Mustacchi 	{						/* 0x00400000 */
467cff040f3SRobert Mustacchi 		AV_386_2_CLFLUSHOPT, STRDESC("AV_386_2_CLFLUSHOPT"),
468cff040f3SRobert Mustacchi 		STRDESC("CLFLUSHOPT"), STRDESC("clflushopt")
469cff040f3SRobert Mustacchi 	},
470cff040f3SRobert Mustacchi 	{						/* 0x00800000 */
471cff040f3SRobert Mustacchi 		AV_386_2_CLWB, STRDESC("AV_386_2_CLWB"),
472cff040f3SRobert Mustacchi 		STRDESC("CLWB"), STRDESC("clwb")
473cff040f3SRobert Mustacchi 	},
474cff040f3SRobert Mustacchi 	{						/* 0x01000000 */
475cff040f3SRobert Mustacchi 		AV_386_2_MONITORX, STRDESC("AV_386_2_MONITORX"),
476cff040f3SRobert Mustacchi 		STRDESC("MONITORX"), STRDESC("monitorx")
477cff040f3SRobert Mustacchi 	},
478cff040f3SRobert Mustacchi 	{						/* 0x02000000 */
479cff040f3SRobert Mustacchi 		AV_386_2_CLZERO, STRDESC("AV_386_2_CLZERO"),
480cff040f3SRobert Mustacchi 		STRDESC("CLZERO"), STRDESC("clzero")
481e4f6ce70SRobert Mustacchi 	},
482e4f6ce70SRobert Mustacchi 	{						/* 0x04000000 */
483e4f6ce70SRobert Mustacchi 		AV_386_2_AVX512_VNNI, STRDESC("AV_386_2_AVX512_VNNI"),
484e4f6ce70SRobert Mustacchi 		STRDESC("AVX512_VNNI"), STRDESC("avx512_vnni")
4855edbd2feSRobert Mustacchi 	},
4865edbd2feSRobert Mustacchi 	{						/* 0x08000000 */
4875edbd2feSRobert Mustacchi 		AV_386_2_VPCLMULQDQ, STRDESC("AV_386_2_VPCLMULQDQ"),
4885edbd2feSRobert Mustacchi 		STRDESC("VPCLMULQDQ"), STRDESC("vpclmulqdq")
4895edbd2feSRobert Mustacchi 	},
4905edbd2feSRobert Mustacchi 	{						/* 0x10000000 */
4915edbd2feSRobert Mustacchi 		AV_386_2_VAES, STRDESC("AV_386_2_VAES"),
4925edbd2feSRobert Mustacchi 		STRDESC("VAES"), STRDESC("vaes")
493*56726c7eSRobert Mustacchi 	},
494*56726c7eSRobert Mustacchi 	{						/* 0x20000000 */
495*56726c7eSRobert Mustacchi 		AV_386_2_GFNI, STRDESC("AV_386_2_GFNI"),
496*56726c7eSRobert Mustacchi 		STRDESC("GFNI"), STRDESC("gfni")
497*56726c7eSRobert Mustacchi 	},
498*56726c7eSRobert Mustacchi 	{						/* 0x40000000 */
499*56726c7eSRobert Mustacchi 		AV_386_2_AVX512_VP2INT, STRDESC("AV_386_2_AVX512_VP2INT"),
500*56726c7eSRobert Mustacchi 		STRDESC("AVX512_VP2INT"), STRDESC("avx512_vp2int")
501*56726c7eSRobert Mustacchi 	},
502*56726c7eSRobert Mustacchi 	{						/* 0x80000000 */
503*56726c7eSRobert Mustacchi 		AV_386_2_AVX512_BITALG, STRDESC("AV_386_2_AVX512_BITALG"),
504*56726c7eSRobert Mustacchi 		STRDESC("AVX512_BITALG"), STRDESC("avx512_bitalg")
505*56726c7eSRobert Mustacchi 	}
506*56726c7eSRobert Mustacchi };
507*56726c7eSRobert Mustacchi 
508*56726c7eSRobert Mustacchi static const elfcap_desc_t hw3_386[ELFCAP_NUM_HW3_386] = {
509*56726c7eSRobert Mustacchi 	{						/* 0x00000001 */
510*56726c7eSRobert Mustacchi 		AV_386_3_AVX512_VBMI2, STRDESC("AV_386_3_AVX512_VBMI2"),
511*56726c7eSRobert Mustacchi 		STRDESC("AVX512_VBMI2"), STRDESC("avx512_vbmi2")
512*56726c7eSRobert Mustacchi 	},
513*56726c7eSRobert Mustacchi 	{						/* 0x00000002 */
514*56726c7eSRobert Mustacchi 		AV_386_3_AVX512_BF16, STRDESC("AV_386_3_AVX512_BF16"),
515*56726c7eSRobert Mustacchi 		STRDESC("AVX512_BF16"), STRDESC("avx512_bf16")
516008b34beSRobert Mustacchi 	}
517ebb8ac07SRobert Mustacchi };
518ebb8ac07SRobert Mustacchi 
5197c478bd9Sstevel@tonic-gate /*
520ae115bc7Smrj  * Concatenate a token to the string buffer.  This can be a capabilities token
5217c478bd9Sstevel@tonic-gate  * or a separator token.
5227c478bd9Sstevel@tonic-gate  */
52399f63845Sab static elfcap_err_t
token(char ** ostr,size_t * olen,const elfcap_str_t * nstr)52499f63845Sab token(char **ostr, size_t *olen, const elfcap_str_t *nstr)
5257c478bd9Sstevel@tonic-gate {
52699f63845Sab 	if (*olen < nstr->s_len)
52799f63845Sab 		return (ELFCAP_ERR_BUFOVFL);
5287c478bd9Sstevel@tonic-gate 
52999f63845Sab 	(void) strcat(*ostr, nstr->s_str);
53099f63845Sab 	*ostr += nstr->s_len;
53199f63845Sab 	*olen -= nstr->s_len;
5327c478bd9Sstevel@tonic-gate 
53399f63845Sab 	return (ELFCAP_ERR_NONE);
53499f63845Sab }
53599f63845Sab 
53699f63845Sab static elfcap_err_t
get_str_desc(elfcap_style_t style,const elfcap_desc_t * cdp,const elfcap_str_t ** ret_str)53799f63845Sab get_str_desc(elfcap_style_t style, const elfcap_desc_t *cdp,
53899f63845Sab     const elfcap_str_t **ret_str)
53999f63845Sab {
54069112eddSAli Bahrami 	switch (ELFCAP_STYLE_MASK(style)) {
54199f63845Sab 	case ELFCAP_STYLE_FULL:
54299f63845Sab 		*ret_str = &cdp->c_full;
54399f63845Sab 		break;
54499f63845Sab 	case ELFCAP_STYLE_UC:
54599f63845Sab 		*ret_str = &cdp->c_uc;
54699f63845Sab 		break;
54799f63845Sab 	case ELFCAP_STYLE_LC:
54899f63845Sab 		*ret_str = &cdp->c_lc;
54999f63845Sab 		break;
55099f63845Sab 	default:
55199f63845Sab 		return (ELFCAP_ERR_INVSTYLE);
55299f63845Sab 	}
55399f63845Sab 
55499f63845Sab 	return (ELFCAP_ERR_NONE);
5557c478bd9Sstevel@tonic-gate }
5567c478bd9Sstevel@tonic-gate 
55799f63845Sab 
5587c478bd9Sstevel@tonic-gate /*
5597c478bd9Sstevel@tonic-gate  * Expand a capabilities value into the strings defined in the associated
5607c478bd9Sstevel@tonic-gate  * capabilities descriptor.
5617c478bd9Sstevel@tonic-gate  */
56299f63845Sab static elfcap_err_t
expand(elfcap_style_t style,elfcap_mask_t val,const elfcap_desc_t * cdp,uint_t cnum,char * str,size_t slen,elfcap_fmt_t fmt)56369112eddSAli Bahrami expand(elfcap_style_t style, elfcap_mask_t val, const elfcap_desc_t *cdp,
56499f63845Sab     uint_t cnum, char *str, size_t slen, elfcap_fmt_t fmt)
5657c478bd9Sstevel@tonic-gate {
56699f63845Sab 	uint_t			cnt;
56799f63845Sab 	int			follow = 0, err;
56899f63845Sab 	const elfcap_str_t	*nstr;
5697c478bd9Sstevel@tonic-gate 
5707c478bd9Sstevel@tonic-gate 	if (val == 0)
57199f63845Sab 		return (ELFCAP_ERR_NONE);
5727c478bd9Sstevel@tonic-gate 
57399f63845Sab 	for (cnt = cnum; cnt > 0; cnt--) {
57499f63845Sab 		uint_t mask = cdp[cnt - 1].c_val;
57599f63845Sab 
57699f63845Sab 		if ((val & mask) != 0) {
5777c478bd9Sstevel@tonic-gate 			if (follow++ && ((err = token(&str, &slen,
57899f63845Sab 			    &format[fmt])) != ELFCAP_ERR_NONE))
5797c478bd9Sstevel@tonic-gate 				return (err);
5807c478bd9Sstevel@tonic-gate 
58199f63845Sab 			err = get_str_desc(style, &cdp[cnt - 1], &nstr);
58299f63845Sab 			if (err != ELFCAP_ERR_NONE)
58399f63845Sab 				return (err);
58499f63845Sab 			if ((err = token(&str, &slen, nstr)) != ELFCAP_ERR_NONE)
5857c478bd9Sstevel@tonic-gate 				return (err);
5867c478bd9Sstevel@tonic-gate 
5877c478bd9Sstevel@tonic-gate 			val = val & ~mask;
5887c478bd9Sstevel@tonic-gate 		}
5897c478bd9Sstevel@tonic-gate 	}
5907c478bd9Sstevel@tonic-gate 
5917c478bd9Sstevel@tonic-gate 	/*
5927c478bd9Sstevel@tonic-gate 	 * If there are any unknown bits remaining display the numeric value.
5937c478bd9Sstevel@tonic-gate 	 */
5947c478bd9Sstevel@tonic-gate 	if (val) {
59599f63845Sab 		if (follow && ((err = token(&str, &slen, &format[fmt])) !=
59699f63845Sab 		    ELFCAP_ERR_NONE))
5977c478bd9Sstevel@tonic-gate 			return (err);
5987c478bd9Sstevel@tonic-gate 
59969112eddSAli Bahrami 		(void) snprintf(str, slen, "0x%x", val);
6007c478bd9Sstevel@tonic-gate 	}
60199f63845Sab 	return (ELFCAP_ERR_NONE);
6027c478bd9Sstevel@tonic-gate }
6037c478bd9Sstevel@tonic-gate 
6047c478bd9Sstevel@tonic-gate /*
6057c478bd9Sstevel@tonic-gate  * Expand a CA_SUNW_HW_1 value.
6067c478bd9Sstevel@tonic-gate  */
60799f63845Sab elfcap_err_t
elfcap_hw1_to_str(elfcap_style_t style,elfcap_mask_t val,char * str,size_t len,elfcap_fmt_t fmt,ushort_t mach)60869112eddSAli Bahrami elfcap_hw1_to_str(elfcap_style_t style, elfcap_mask_t val, char *str,
60999f63845Sab     size_t len, elfcap_fmt_t fmt, ushort_t mach)
6107c478bd9Sstevel@tonic-gate {
6117c478bd9Sstevel@tonic-gate 	/*
6127c478bd9Sstevel@tonic-gate 	 * Initialize the string buffer, and validate the format request.
6137c478bd9Sstevel@tonic-gate 	 */
6147c478bd9Sstevel@tonic-gate 	*str = '\0';
61599f63845Sab 	if ((fmt < 0) || (fmt >= FORMAT_NELTS))
61699f63845Sab 		return (ELFCAP_ERR_INVFMT);
6177c478bd9Sstevel@tonic-gate 
6187c478bd9Sstevel@tonic-gate 	if ((mach == EM_386) || (mach == EM_IA_64) || (mach == EM_AMD64))
61999f63845Sab 		return (expand(style, val, &hw1_386[0], ELFCAP_NUM_HW1_386,
62099f63845Sab 		    str, len, fmt));
6217c478bd9Sstevel@tonic-gate 
6227c478bd9Sstevel@tonic-gate 	if ((mach == EM_SPARC) || (mach == EM_SPARC32PLUS) ||
6237c478bd9Sstevel@tonic-gate 	    (mach == EM_SPARCV9))
62499f63845Sab 		return (expand(style, val, hw1_sparc, ELFCAP_NUM_HW1_SPARC,
62599f63845Sab 		    str, len, fmt));
6267c478bd9Sstevel@tonic-gate 
62799f63845Sab 	return (ELFCAP_ERR_UNKMACH);
6287c478bd9Sstevel@tonic-gate }
6297c478bd9Sstevel@tonic-gate 
63069112eddSAli Bahrami /*
631ebb8ac07SRobert Mustacchi  * Expand a CA_SUNW_HW_2 value.
63269112eddSAli Bahrami  */
63369112eddSAli Bahrami elfcap_err_t
elfcap_hw2_to_str(elfcap_style_t style,elfcap_mask_t val,char * str,size_t len,elfcap_fmt_t fmt,ushort_t mach)63469112eddSAli Bahrami elfcap_hw2_to_str(elfcap_style_t style, elfcap_mask_t val, char *str,
63569112eddSAli Bahrami     size_t len, elfcap_fmt_t fmt, ushort_t mach)
63669112eddSAli Bahrami {
63769112eddSAli Bahrami 	/*
63869112eddSAli Bahrami 	 * Initialize the string buffer, and validate the format request.
63969112eddSAli Bahrami 	 */
64069112eddSAli Bahrami 	*str = '\0';
64169112eddSAli Bahrami 	if ((fmt < 0) || (fmt >= FORMAT_NELTS))
64269112eddSAli Bahrami 		return (ELFCAP_ERR_INVFMT);
64369112eddSAli Bahrami 
644ebb8ac07SRobert Mustacchi 	if ((mach == EM_386) || (mach == EM_IA_64) || (mach == EM_AMD64))
645ebb8ac07SRobert Mustacchi 		return (expand(style, val, &hw2_386[0], ELFCAP_NUM_HW2_386,
646ebb8ac07SRobert Mustacchi 		    str, len, fmt));
647ebb8ac07SRobert Mustacchi 
64869112eddSAli Bahrami 	return (expand(style, val, NULL, 0, str, len, fmt));
64969112eddSAli Bahrami }
65069112eddSAli Bahrami 
651*56726c7eSRobert Mustacchi /*
652*56726c7eSRobert Mustacchi  * Expand a CA_SUNW_HW_3 value.
653*56726c7eSRobert Mustacchi  */
654*56726c7eSRobert Mustacchi elfcap_err_t
elfcap_hw3_to_str(elfcap_style_t style,elfcap_mask_t val,char * str,size_t len,elfcap_fmt_t fmt,ushort_t mach)655*56726c7eSRobert Mustacchi elfcap_hw3_to_str(elfcap_style_t style, elfcap_mask_t val, char *str,
656*56726c7eSRobert Mustacchi     size_t len, elfcap_fmt_t fmt, ushort_t mach)
657*56726c7eSRobert Mustacchi {
658*56726c7eSRobert Mustacchi 	/*
659*56726c7eSRobert Mustacchi 	 * Initialize the string buffer, and validate the format request.
660*56726c7eSRobert Mustacchi 	 */
661*56726c7eSRobert Mustacchi 	*str = '\0';
662*56726c7eSRobert Mustacchi 	if ((fmt < 0) || (fmt >= FORMAT_NELTS))
663*56726c7eSRobert Mustacchi 		return (ELFCAP_ERR_INVFMT);
664*56726c7eSRobert Mustacchi 
665*56726c7eSRobert Mustacchi 	if ((mach == EM_386) || (mach == EM_IA_64) || (mach == EM_AMD64))
666*56726c7eSRobert Mustacchi 		return (expand(style, val, &hw3_386[0], ELFCAP_NUM_HW3_386,
667*56726c7eSRobert Mustacchi 		    str, len, fmt));
668*56726c7eSRobert Mustacchi 
669*56726c7eSRobert Mustacchi 	return (expand(style, val, NULL, 0, str, len, fmt));
670*56726c7eSRobert Mustacchi }
671*56726c7eSRobert Mustacchi 
6727c478bd9Sstevel@tonic-gate /*
6737c478bd9Sstevel@tonic-gate  * Expand a CA_SUNW_SF_1 value.  Note, that at present these capabilities are
6747c478bd9Sstevel@tonic-gate  * common across all platforms.  The use of "mach" is therefore redundant, but
67599f63845Sab  * is retained for compatibility with the interface of elfcap_hw1_to_str(), and
6767c478bd9Sstevel@tonic-gate  * possible future expansion.
6777c478bd9Sstevel@tonic-gate  */
67899f63845Sab elfcap_err_t
6797c478bd9Sstevel@tonic-gate /* ARGSUSED4 */
elfcap_sf1_to_str(elfcap_style_t style,elfcap_mask_t val,char * str,size_t len,elfcap_fmt_t fmt,ushort_t mach)68069112eddSAli Bahrami elfcap_sf1_to_str(elfcap_style_t style, elfcap_mask_t val, char *str,
68199f63845Sab     size_t len, elfcap_fmt_t fmt, ushort_t mach)
6827c478bd9Sstevel@tonic-gate {
6837c478bd9Sstevel@tonic-gate 	/*
6847c478bd9Sstevel@tonic-gate 	 * Initialize the string buffer, and validate the format request.
6857c478bd9Sstevel@tonic-gate 	 */
6867c478bd9Sstevel@tonic-gate 	*str = '\0';
68799f63845Sab 	if ((fmt < 0) || (fmt >= FORMAT_NELTS))
68899f63845Sab 		return (ELFCAP_ERR_INVFMT);
6897c478bd9Sstevel@tonic-gate 
69099f63845Sab 	return (expand(style, val, &sf1[0], ELFCAP_NUM_SF1, str, len, fmt));
6917c478bd9Sstevel@tonic-gate }
6927c478bd9Sstevel@tonic-gate 
6937c478bd9Sstevel@tonic-gate /*
69499f63845Sab  * Given a capability tag type and value, map it to a string representation.
6957c478bd9Sstevel@tonic-gate  */
69699f63845Sab elfcap_err_t
elfcap_tag_to_str(elfcap_style_t style,uint64_t tag,elfcap_mask_t val,char * str,size_t len,elfcap_fmt_t fmt,ushort_t mach)69769112eddSAli Bahrami elfcap_tag_to_str(elfcap_style_t style, uint64_t tag, elfcap_mask_t val,
69899f63845Sab     char *str, size_t len, elfcap_fmt_t fmt, ushort_t mach)
6997c478bd9Sstevel@tonic-gate {
70069112eddSAli Bahrami 	switch (tag) {
70169112eddSAli Bahrami 	case CA_SUNW_HW_1:
70299f63845Sab 		return (elfcap_hw1_to_str(style, val, str, len, fmt, mach));
70369112eddSAli Bahrami 
70469112eddSAli Bahrami 	case CA_SUNW_SF_1:
70599f63845Sab 		return (elfcap_sf1_to_str(style, val, str, len, fmt, mach));
7067c478bd9Sstevel@tonic-gate 
70769112eddSAli Bahrami 	case CA_SUNW_HW_2:
70869112eddSAli Bahrami 		return (elfcap_hw2_to_str(style, val, str, len, fmt, mach));
70969112eddSAli Bahrami 
710*56726c7eSRobert Mustacchi 	case CA_SUNW_HW_3:
711*56726c7eSRobert Mustacchi 		return (elfcap_hw3_to_str(style, val, str, len, fmt, mach));
712*56726c7eSRobert Mustacchi 
71369112eddSAli Bahrami 	}
71469112eddSAli Bahrami 
71599f63845Sab 	return (ELFCAP_ERR_UNKTAG);
7167c478bd9Sstevel@tonic-gate }
7177c478bd9Sstevel@tonic-gate 
7187c478bd9Sstevel@tonic-gate /*
7197c478bd9Sstevel@tonic-gate  * Determine a capabilities value from a capabilities string.
7207c478bd9Sstevel@tonic-gate  */
72169112eddSAli Bahrami static elfcap_mask_t
value(elfcap_style_t style,const char * str,const elfcap_desc_t * cdp,uint_t cnum)72299f63845Sab value(elfcap_style_t style, const char *str, const elfcap_desc_t *cdp,
72399f63845Sab     uint_t cnum)
7247c478bd9Sstevel@tonic-gate {
72599f63845Sab 	const elfcap_str_t	*nstr;
7267c478bd9Sstevel@tonic-gate 	uint_t	num;
72799f63845Sab 	int	err;
7287c478bd9Sstevel@tonic-gate 
7297c478bd9Sstevel@tonic-gate 	for (num = 0; num < cnum; num++) {
73099f63845Sab 		/*
73199f63845Sab 		 * Skip "reserved" bits. These are unassigned bits in the
73299f63845Sab 		 * middle of the assigned range.
73399f63845Sab 		 */
73499f63845Sab 		if (cdp[num].c_val == 0)
73599f63845Sab 			continue;
73699f63845Sab 
73799f63845Sab 		if ((err = get_str_desc(style, &cdp[num], &nstr)) != 0)
73899f63845Sab 			return (err);
73969112eddSAli Bahrami 		if (style & ELFCAP_STYLE_F_ICMP) {
74069112eddSAli Bahrami 			if (strcasecmp(str, nstr->s_str) == 0)
74169112eddSAli Bahrami 				return (cdp[num].c_val);
74269112eddSAli Bahrami 		} else {
74369112eddSAli Bahrami 			if (strcmp(str, nstr->s_str) == 0)
74469112eddSAli Bahrami 				return (cdp[num].c_val);
74569112eddSAli Bahrami 		}
7467c478bd9Sstevel@tonic-gate 	}
74769112eddSAli Bahrami 
7487c478bd9Sstevel@tonic-gate 	return (0);
7497c478bd9Sstevel@tonic-gate }
7507c478bd9Sstevel@tonic-gate 
75169112eddSAli Bahrami elfcap_mask_t
elfcap_sf1_from_str(elfcap_style_t style,const char * str,ushort_t mach)75299f63845Sab elfcap_sf1_from_str(elfcap_style_t style, const char *str, ushort_t mach)
7537c478bd9Sstevel@tonic-gate {
75499f63845Sab 	return (value(style, str, &sf1[0], ELFCAP_NUM_SF1));
7557c478bd9Sstevel@tonic-gate }
7567c478bd9Sstevel@tonic-gate 
75769112eddSAli Bahrami elfcap_mask_t
elfcap_hw1_from_str(elfcap_style_t style,const char * str,ushort_t mach)75899f63845Sab elfcap_hw1_from_str(elfcap_style_t style, const char *str, ushort_t mach)
7597c478bd9Sstevel@tonic-gate {
7607c478bd9Sstevel@tonic-gate 	if ((mach == EM_386) || (mach == EM_IA_64) || (mach == EM_AMD64))
76199f63845Sab 		return (value(style, str, &hw1_386[0], ELFCAP_NUM_HW1_386));
7627c478bd9Sstevel@tonic-gate 
7637c478bd9Sstevel@tonic-gate 	if ((mach == EM_SPARC) || (mach == EM_SPARC32PLUS) ||
7647c478bd9Sstevel@tonic-gate 	    (mach == EM_SPARCV9))
76599f63845Sab 		return (value(style, str, hw1_sparc, ELFCAP_NUM_HW1_SPARC));
7667c478bd9Sstevel@tonic-gate 
7677c478bd9Sstevel@tonic-gate 	return (0);
7687c478bd9Sstevel@tonic-gate }
76969112eddSAli Bahrami elfcap_mask_t
elfcap_hw2_from_str(elfcap_style_t style,const char * str,ushort_t mach)77069112eddSAli Bahrami elfcap_hw2_from_str(elfcap_style_t style, const char *str, ushort_t mach)
77169112eddSAli Bahrami {
772ebb8ac07SRobert Mustacchi 	if ((mach == EM_386) || (mach == EM_IA_64) || (mach == EM_AMD64))
773ebb8ac07SRobert Mustacchi 		return (value(style, str, &hw2_386[0], ELFCAP_NUM_HW2_386));
774ebb8ac07SRobert Mustacchi 
77569112eddSAli Bahrami 	return (0);
77669112eddSAli Bahrami }
777*56726c7eSRobert Mustacchi elfcap_mask_t
elfcap_hw3_from_str(elfcap_style_t style,const char * str,ushort_t mach)778*56726c7eSRobert Mustacchi elfcap_hw3_from_str(elfcap_style_t style, const char *str, ushort_t mach)
779*56726c7eSRobert Mustacchi {
780*56726c7eSRobert Mustacchi 	if ((mach == EM_386) || (mach == EM_IA_64) || (mach == EM_AMD64))
781*56726c7eSRobert Mustacchi 		return (value(style, str, &hw3_386[0], ELFCAP_NUM_HW3_386));
782*56726c7eSRobert Mustacchi 
783*56726c7eSRobert Mustacchi 	return (0);
784*56726c7eSRobert Mustacchi }
785*56726c7eSRobert Mustacchi 
78669112eddSAli Bahrami 
78769112eddSAli Bahrami /*
78869112eddSAli Bahrami  * Given a capability tag type and value, return the capabilities values
78969112eddSAli Bahrami  * contained in the string.
79069112eddSAli Bahrami  */
79169112eddSAli Bahrami elfcap_mask_t
elfcap_tag_from_str(elfcap_style_t style,uint64_t tag,const char * str,ushort_t mach)79269112eddSAli Bahrami elfcap_tag_from_str(elfcap_style_t style, uint64_t tag, const char *str,
79369112eddSAli Bahrami     ushort_t mach)
79469112eddSAli Bahrami {
79569112eddSAli Bahrami 	switch (tag) {
79669112eddSAli Bahrami 	case CA_SUNW_HW_1:
79769112eddSAli Bahrami 		return (elfcap_hw1_from_str(style, str, mach));
79869112eddSAli Bahrami 
79969112eddSAli Bahrami 	case CA_SUNW_SF_1:
80069112eddSAli Bahrami 		return (elfcap_sf1_from_str(style, str, mach));
80169112eddSAli Bahrami 
80269112eddSAli Bahrami 	case CA_SUNW_HW_2:
80369112eddSAli Bahrami 		return (elfcap_hw2_from_str(style, str, mach));
804*56726c7eSRobert Mustacchi 
805*56726c7eSRobert Mustacchi 	case CA_SUNW_HW_3:
806*56726c7eSRobert Mustacchi 		return (elfcap_hw3_from_str(style, str, mach));
80769112eddSAli Bahrami 	}
80869112eddSAli Bahrami 
80969112eddSAli Bahrami 	return (0);
81069112eddSAli Bahrami }
81199f63845Sab 
81299f63845Sab /*
81399f63845Sab  * These functions allow the caller to get direct access to the
81499f63845Sab  * cap descriptors.
81599f63845Sab  */
816*56726c7eSRobert Mustacchi const elfcap_str_t *
elfcap_getdesc_formats(void)817*56726c7eSRobert Mustacchi elfcap_getdesc_formats(void)
818*56726c7eSRobert Mustacchi {
819*56726c7eSRobert Mustacchi 	return (format);
820*56726c7eSRobert Mustacchi }
821*56726c7eSRobert Mustacchi 
82299f63845Sab const elfcap_desc_t *
elfcap_getdesc_hw1_sparc(void)82399f63845Sab elfcap_getdesc_hw1_sparc(void)
82499f63845Sab {
82599f63845Sab 	return (hw1_sparc);
82699f63845Sab }
82799f63845Sab 
82899f63845Sab const elfcap_desc_t *
elfcap_getdesc_hw1_386(void)82999f63845Sab elfcap_getdesc_hw1_386(void)
83099f63845Sab {
83199f63845Sab 	return (hw1_386);
83299f63845Sab }
83399f63845Sab 
83499f63845Sab const elfcap_desc_t *
elfcap_getdesc_sf1(void)83599f63845Sab elfcap_getdesc_sf1(void)
83699f63845Sab {
83799f63845Sab 	return (sf1);
83899f63845Sab }
839*56726c7eSRobert Mustacchi 
840*56726c7eSRobert Mustacchi const elfcap_desc_t *
elfcap_getdesc_hw2_386(void)841*56726c7eSRobert Mustacchi elfcap_getdesc_hw2_386(void)
842*56726c7eSRobert Mustacchi {
843*56726c7eSRobert Mustacchi 	return (hw2_386);
844*56726c7eSRobert Mustacchi }
845*56726c7eSRobert Mustacchi 
846*56726c7eSRobert Mustacchi const elfcap_desc_t *
elfcap_getdesc_hw3_386(void)847*56726c7eSRobert Mustacchi elfcap_getdesc_hw3_386(void)
848*56726c7eSRobert Mustacchi {
849*56726c7eSRobert Mustacchi 	return (hw3_386);
850*56726c7eSRobert Mustacchi }
851