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 55aefb655Srie * Common Development and Distribution License (the "License"). 65aefb655Srie * 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 */ 215aefb655Srie 227c478bd9Sstevel@tonic-gate /* 23*4f680cc6SAli Bahrami * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate /* 287c478bd9Sstevel@tonic-gate * String conversion routine for version flag entries. 297c478bd9Sstevel@tonic-gate */ 307c478bd9Sstevel@tonic-gate #include <stdio.h> 317c478bd9Sstevel@tonic-gate #include "_conv.h" 327c478bd9Sstevel@tonic-gate #include "version_msg.h" 337c478bd9Sstevel@tonic-gate 34090a8d9eSAli Bahrami #define VERFLAGSZ CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \ 35090a8d9eSAli Bahrami MSG_VER_FLG_WEAK_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 36090a8d9eSAli Bahrami MSG_VER_FLG_BASE_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 37090a8d9eSAli Bahrami MSG_VER_FLG_INFO_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 38090a8d9eSAli Bahrami CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE 39090a8d9eSAli Bahrami 40090a8d9eSAli Bahrami /* 41090a8d9eSAli Bahrami * Ensure that Conv_ver_flags_buf_t is large enough: 42090a8d9eSAli Bahrami * 43090a8d9eSAli Bahrami * VERFLAGSZ is the real minimum size of the buffer required by 44090a8d9eSAli Bahrami * conv_ver_flags(). However, Conv_ver_flags_buf_t uses CONV_VER_FLAGS_BUFSIZE 45090a8d9eSAli Bahrami * to set the buffer size. We do things this way because the definition of 46090a8d9eSAli Bahrami * VERFLAGSZ uses information that is not available in the environment of 47090a8d9eSAli Bahrami * other programs that include the conv.h header file. 48090a8d9eSAli Bahrami */ 49090a8d9eSAli Bahrami #if (CONV_VER_FLAGS_BUFSIZE != VERFLAGSZ) && !defined(__lint) 50090a8d9eSAli Bahrami #define REPORT_BUFSIZE VERFLAGSZ 51090a8d9eSAli Bahrami #include "report_bufsize.h" 52090a8d9eSAli Bahrami #error "CONV_VER_FLAGS_BUFSIZE does not match VERFLAGSZ" 53090a8d9eSAli Bahrami #endif 54090a8d9eSAli Bahrami 557c478bd9Sstevel@tonic-gate const char * 56090a8d9eSAli Bahrami conv_ver_flags(Half flags, Conv_fmt_flags_t fmt_flags, 57090a8d9eSAli Bahrami Conv_ver_flags_buf_t *ver_flags_buf) 587c478bd9Sstevel@tonic-gate { 59*4f680cc6SAli Bahrami static const Val_desc vda[] = { 60*4f680cc6SAli Bahrami { VER_FLG_WEAK, MSG_VER_FLG_WEAK }, 61*4f680cc6SAli Bahrami { VER_FLG_BASE, MSG_VER_FLG_BASE }, 62*4f680cc6SAli Bahrami { VER_FLG_INFO, MSG_VER_FLG_INFO }, 63090a8d9eSAli Bahrami { 0, 0 } 64090a8d9eSAli Bahrami }; 65090a8d9eSAli Bahrami static CONV_EXPN_FIELD_ARG conv_arg = { 66*4f680cc6SAli Bahrami NULL, sizeof (ver_flags_buf->buf) }; 67090a8d9eSAli Bahrami 68090a8d9eSAli Bahrami if (flags == 0) 697c478bd9Sstevel@tonic-gate return (MSG_ORIG(MSG_GBL_NULL)); 70090a8d9eSAli Bahrami 71090a8d9eSAli Bahrami conv_arg.buf = ver_flags_buf->buf; 72090a8d9eSAli Bahrami conv_arg.oflags = conv_arg.rflags = flags; 73*4f680cc6SAli Bahrami (void) conv_expn_field(&conv_arg, vda, fmt_flags); 74090a8d9eSAli Bahrami 75090a8d9eSAli Bahrami return ((const char *)ver_flags_buf->buf); 767c478bd9Sstevel@tonic-gate } 773b41b08bSab196087 783b41b08bSab196087 793b41b08bSab196087 /* 803b41b08bSab196087 * Format a version index as contained in a VERSYM section 81d840867fSab196087 * 82d840867fSab196087 * entry: 83d840867fSab196087 * verndx - Version index to format 84d840867fSab196087 * gnuver - If True (non-zero), the version rules used by the 85d840867fSab196087 * GNU ld are assumed. If False (0), Solaris ld rules apply. 863b41b08bSab196087 */ 873b41b08bSab196087 const char * 88de777a60Sab196087 conv_ver_index(Versym verndx, int gnuver, Conv_inv_buf_t *inv_buf) 893b41b08bSab196087 { 90d840867fSab196087 const char *fmt; 913b41b08bSab196087 923b41b08bSab196087 /* Special case versions starting at VER_NDX_LORESERVE */ 933b41b08bSab196087 if (verndx == VER_NDX_ELIMINATE) 943b41b08bSab196087 return (MSG_ORIG(MSG_VERSYM_ELIMINATE)); 953b41b08bSab196087 96d840867fSab196087 /* 97d840867fSab196087 * The GNU style of versioning uses the top bit of the 98d840867fSab196087 * 16-bit version index (0x8000) as a "hidden bit". A 99d840867fSab196087 * hidden symbol is supposed to be ignored by the linker. 100d840867fSab196087 */ 101d840867fSab196087 if (gnuver && (verndx & 0x8000)) { 102d840867fSab196087 verndx &= ~0x8000; 103d840867fSab196087 fmt = MSG_ORIG(MSG_VERSYM_GNUH_FMT); 104d840867fSab196087 } else { 105d840867fSab196087 fmt = MSG_ORIG(MSG_VERSYM_FMT); 106d840867fSab196087 } 107d840867fSab196087 1083b41b08bSab196087 /* format as numeric */ 109de777a60Sab196087 (void) snprintf(inv_buf->buf, sizeof (inv_buf->buf), 110de777a60Sab196087 fmt, EC_HALF(verndx)); 111de777a60Sab196087 return (inv_buf->buf); 1123b41b08bSab196087 } 113