14f680cc6SAli Bahrami /* 24f680cc6SAli Bahrami * CDDL HEADER START 34f680cc6SAli Bahrami * 44f680cc6SAli Bahrami * The contents of this file are subject to the terms of the 54f680cc6SAli Bahrami * Common Development and Distribution License (the "License"). 64f680cc6SAli Bahrami * You may not use this file except in compliance with the License. 74f680cc6SAli Bahrami * 84f680cc6SAli Bahrami * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 94f680cc6SAli Bahrami * or http://www.opensolaris.org/os/licensing. 104f680cc6SAli Bahrami * See the License for the specific language governing permissions 114f680cc6SAli Bahrami * and limitations under the License. 124f680cc6SAli Bahrami * 134f680cc6SAli Bahrami * When distributing Covered Code, include this CDDL HEADER in each 144f680cc6SAli Bahrami * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 154f680cc6SAli Bahrami * If applicable, add the following below this CDDL HEADER, with the 164f680cc6SAli Bahrami * fields enclosed by brackets "[]" replaced with your own identifying 174f680cc6SAli Bahrami * information: Portions Copyright [yyyy] [name of copyright owner] 184f680cc6SAli Bahrami * 194f680cc6SAli Bahrami * CDDL HEADER END 204f680cc6SAli Bahrami */ 214f680cc6SAli Bahrami 224f680cc6SAli Bahrami /* 23*08278a5eSRod Evans * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 244f680cc6SAli Bahrami * Use is subject to license terms. 254f680cc6SAli Bahrami */ 264f680cc6SAli Bahrami 274f680cc6SAli Bahrami /* 284f680cc6SAli Bahrami * String conversion routine for hardware capabilities types. 294f680cc6SAli Bahrami */ 304f680cc6SAli Bahrami #include <strings.h> 314f680cc6SAli Bahrami #include <stdio.h> 324f680cc6SAli Bahrami #include <_machelf.h> 334f680cc6SAli Bahrami #include <elfcap.h> 344f680cc6SAli Bahrami #include "cap_msg.h" 354f680cc6SAli Bahrami #include "_conv.h" 364f680cc6SAli Bahrami 374f680cc6SAli Bahrami static int 38*08278a5eSRod Evans conv_cap(Xword val, char *str, size_t len, Half mach, 394f680cc6SAli Bahrami Conv_fmt_flags_t fmt_flags, elfcap_to_str_func_t *fptr) 404f680cc6SAli Bahrami { 414f680cc6SAli Bahrami size_t _len; 424f680cc6SAli Bahrami int do_bkt = (fmt_flags & CONV_FMT_NOBKT) == 0; 434f680cc6SAli Bahrami 444f680cc6SAli Bahrami /* 454f680cc6SAli Bahrami * Note that for the purposes of this routine, I consider 464f680cc6SAli Bahrami * CONV_FMT_NOBKT to mean no brackets, or anything that 474f680cc6SAli Bahrami * is placed outside of them. We also drop the hex version 484f680cc6SAli Bahrami * of the flags that are put in front of the opening bracket. 494f680cc6SAli Bahrami */ 504f680cc6SAli Bahrami if (do_bkt) { 514f680cc6SAli Bahrami _len = sprintf(str, MSG_ORIG(MSG_GBL_OSQBRKT), EC_XWORD(val)); 524f680cc6SAli Bahrami 534f680cc6SAli Bahrami len -= _len; 544f680cc6SAli Bahrami str += _len; 554f680cc6SAli Bahrami } 564f680cc6SAli Bahrami 574f680cc6SAli Bahrami if ((*fptr)(ELFCAP_STYLE_UC, val, str, len, ELFCAP_FMT_SNGSPACE, 584f680cc6SAli Bahrami mach) != 0) 594f680cc6SAli Bahrami return (0); 604f680cc6SAli Bahrami 614f680cc6SAli Bahrami if (do_bkt) { 624f680cc6SAli Bahrami _len = strlen(str); 634f680cc6SAli Bahrami if ((len - _len) >= MSG_GBL_CSQBRKT_SIZE) { 644f680cc6SAli Bahrami str += _len; 654f680cc6SAli Bahrami (void) strcpy(str, MSG_ORIG(MSG_GBL_CSQBRKT)); 664f680cc6SAli Bahrami } 674f680cc6SAli Bahrami } 684f680cc6SAli Bahrami return (1); 694f680cc6SAli Bahrami } 704f680cc6SAli Bahrami 714f680cc6SAli Bahrami const char * 724f680cc6SAli Bahrami conv_cap_val_hw1(Xword val, Half mach, Conv_fmt_flags_t fmt_flags, 734f680cc6SAli Bahrami Conv_cap_val_hw1_buf_t *cap_val_hw1_buf) 744f680cc6SAli Bahrami { 754f680cc6SAli Bahrami if (val == 0) 764f680cc6SAli Bahrami return (MSG_ORIG(MSG_GBL_ZERO)); 774f680cc6SAli Bahrami 78*08278a5eSRod Evans if (conv_cap(val, cap_val_hw1_buf->buf, sizeof (cap_val_hw1_buf->buf), 794f680cc6SAli Bahrami mach, fmt_flags, elfcap_hw1_to_str) == 0) 804f680cc6SAli Bahrami return (conv_invalid_val(&cap_val_hw1_buf->inv_buf, val, 0)); 814f680cc6SAli Bahrami return ((const char *)cap_val_hw1_buf->buf); 824f680cc6SAli Bahrami } 834f680cc6SAli Bahrami 844f680cc6SAli Bahrami const char * 85*08278a5eSRod Evans conv_cap_val_hw2(Xword val, Half mach, Conv_fmt_flags_t fmt_flags, 86*08278a5eSRod Evans Conv_cap_val_hw2_buf_t *cap_val_hw2_buf) 87*08278a5eSRod Evans { 88*08278a5eSRod Evans if (val == 0) 89*08278a5eSRod Evans return (MSG_ORIG(MSG_GBL_ZERO)); 90*08278a5eSRod Evans 91*08278a5eSRod Evans if (conv_cap(val, cap_val_hw2_buf->buf, sizeof (cap_val_hw2_buf->buf), 92*08278a5eSRod Evans mach, fmt_flags, elfcap_hw2_to_str) == 0) 93*08278a5eSRod Evans return (conv_invalid_val(&cap_val_hw2_buf->inv_buf, val, 0)); 94*08278a5eSRod Evans return ((const char *)cap_val_hw2_buf->buf); 95*08278a5eSRod Evans } 96*08278a5eSRod Evans 97*08278a5eSRod Evans const char * 984f680cc6SAli Bahrami conv_cap_val_sf1(Xword val, Half mach, Conv_fmt_flags_t fmt_flags, 994f680cc6SAli Bahrami Conv_cap_val_sf1_buf_t *cap_val_sf1_buf) 1004f680cc6SAli Bahrami { 1014f680cc6SAli Bahrami if (val == 0) 1024f680cc6SAli Bahrami return (MSG_ORIG(MSG_GBL_ZERO)); 1034f680cc6SAli Bahrami 104*08278a5eSRod Evans if (conv_cap(val, cap_val_sf1_buf->buf, sizeof (cap_val_sf1_buf->buf), 1054f680cc6SAli Bahrami mach, fmt_flags, elfcap_sf1_to_str) == 0) 1064f680cc6SAli Bahrami return (conv_invalid_val(&cap_val_sf1_buf->inv_buf, val, 0)); 1074f680cc6SAli Bahrami return ((const char *)cap_val_sf1_buf->buf); 1084f680cc6SAli Bahrami } 1094f680cc6SAli Bahrami 1104f680cc6SAli Bahrami const char * 1114f680cc6SAli Bahrami conv_cap_tag(Xword tag, Conv_fmt_flags_t fmt_flags, Conv_inv_buf_t *inv_buf) 1124f680cc6SAli Bahrami { 1134f680cc6SAli Bahrami #ifdef _ELF64 1144f680cc6SAli Bahrami /* 1154f680cc6SAli Bahrami * Valid tags all fit in 32-bits, so a value larger than that 1164f680cc6SAli Bahrami * is garbage. conv_map_ds() sees 32-bit values, so test for garbage 1174f680cc6SAli Bahrami * here before passing it on. 1184f680cc6SAli Bahrami * 1194f680cc6SAli Bahrami * Since there are no valid tags with a value > 32-bits, there 1204f680cc6SAli Bahrami * is no reason to expend effort decoding the low order bits. 1214f680cc6SAli Bahrami */ 1224f680cc6SAli Bahrami if (tag & 0xffffffff00000000) 1234f680cc6SAli Bahrami return (conv_invalid_val(inv_buf, tag, fmt_flags)); 1244f680cc6SAli Bahrami #endif 1254f680cc6SAli Bahrami 1264f680cc6SAli Bahrami return (conv_map_ds(ELFOSABI_NONE, EM_NONE, tag, 1274f680cc6SAli Bahrami conv_cap_tag_strings(fmt_flags), fmt_flags, inv_buf)); 1284f680cc6SAli Bahrami } 1294f680cc6SAli Bahrami 1304f680cc6SAli Bahrami const char * 131*08278a5eSRod Evans conv_cap_val(Xword tag, Xword val, Half mach, Conv_fmt_flags_t fmt_flags, 132*08278a5eSRod Evans Conv_cap_val_buf_t *cap_val_buf) 1334f680cc6SAli Bahrami { 134*08278a5eSRod Evans switch (tag) { 135*08278a5eSRod Evans case CA_SUNW_HW_1: 136*08278a5eSRod Evans return (conv_cap_val_hw1(val, mach, fmt_flags, 1374f680cc6SAli Bahrami &cap_val_buf->cap_val_hw1_buf)); 138*08278a5eSRod Evans 139*08278a5eSRod Evans case CA_SUNW_SF_1: 140*08278a5eSRod Evans return (conv_cap_val_sf1(val, mach, fmt_flags, 1414f680cc6SAli Bahrami &cap_val_buf->cap_val_sf1_buf)); 142*08278a5eSRod Evans 143*08278a5eSRod Evans case CA_SUNW_HW_2: 144*08278a5eSRod Evans return (conv_cap_val_hw2(val, mach, fmt_flags, 145*08278a5eSRod Evans &cap_val_buf->cap_val_hw2_buf)); 146*08278a5eSRod Evans 147*08278a5eSRod Evans default: 1484f680cc6SAli Bahrami return (conv_invalid_val(&cap_val_buf->inv_buf, val, 0)); 1494f680cc6SAli Bahrami } 150*08278a5eSRod Evans } 151