xref: /onnv-gate/usr/src/cmd/sgs/libconv/common/dynamic.c (revision 6206:6b0ed502a8e7)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51618Srie  * Common Development and Distribution License (the "License").
61618Srie  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
211618Srie 
220Sstevel@tonic-gate /*
23*6206Sab196087  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate /*
290Sstevel@tonic-gate  * String conversion routine for .dynamic tag entries.
300Sstevel@tonic-gate  */
310Sstevel@tonic-gate #include	<stdio.h>
320Sstevel@tonic-gate #include	<string.h>
330Sstevel@tonic-gate #include	<sys/elf_SPARC.h>
34280Srie #include	"rtld.h"
350Sstevel@tonic-gate #include	"_conv.h"
360Sstevel@tonic-gate #include	"dynamic_msg.h"
370Sstevel@tonic-gate 
383492Sab196087 
393492Sab196087 
403492Sab196087 /* Instantiate a local copy of conv_map2str() from _conv.h */
413492Sab196087 DEFINE_conv_map2str
423492Sab196087 
433492Sab196087 
443492Sab196087 
452352Sab196087 #define	POSSZ	CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
462352Sab196087 		MSG_DFP_LAZYLOAD_ALT_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
472352Sab196087 		MSG_DFP_GROUPPERM_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
484734Sab196087 		CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
494734Sab196087 
504734Sab196087 /*
514734Sab196087  * Ensure that Conv_dyn_posflag1_buf_t is large enough:
524734Sab196087  *
534734Sab196087  * POSSZ is the real minimum size of the buffer required by conv_dyn_posflag1().
544734Sab196087  * However, Conv_dyn_posflag1_buf_t uses CONV_DYN_POSFLAG1_BUFSIZE to set the
554734Sab196087  * buffer size. We do things this way because the definition of POSSZ uses
564734Sab196087  * information that is not available in the environment of other programs
574734Sab196087  * that include the conv.h header file.
584734Sab196087  */
595152Sab196087 #if (CONV_DYN_POSFLAG1_BUFSIZE != POSSZ) && !defined(__lint)
605152Sab196087 #define	REPORT_BUFSIZE POSSZ
615152Sab196087 #include "report_bufsize.h"
625152Sab196087 #error "CONV_DYN_POSFLAG1_BUFSIZE does not match POSSZ"
634734Sab196087 #endif
640Sstevel@tonic-gate 
650Sstevel@tonic-gate const char *
665088Sab196087 conv_dyn_posflag1(Xword flags, Conv_fmt_flags_t fmt_flags,
674734Sab196087     Conv_dyn_posflag1_buf_t *dyn_posflag1_buf)
680Sstevel@tonic-gate {
691618Srie 	static Val_desc vda[] = {
701618Srie 		{ DF_P1_LAZYLOAD,	MSG_ORIG(MSG_DFP_LAZYLOAD) },
711618Srie 		{ DF_P1_GROUPPERM,	MSG_ORIG(MSG_DFP_GROUPPERM) },
721618Srie 		{ 0,			0 }
731618Srie 	};
744734Sab196087 	static CONV_EXPN_FIELD_ARG conv_arg = {
754734Sab196087 	    NULL, sizeof (dyn_posflag1_buf->buf), vda };
762352Sab196087 	static Val_desc vda_alt[] = {
772352Sab196087 		{ DF_P1_LAZYLOAD,	MSG_ORIG(MSG_DFP_LAZYLOAD_ALT) },
782352Sab196087 		{ DF_P1_GROUPPERM,	MSG_ORIG(MSG_DFP_GROUPPERM) },
792352Sab196087 		{ 0,			0 }
802352Sab196087 	};
814734Sab196087 	static CONV_EXPN_FIELD_ARG conv_arg_alt = {
824734Sab196087 	    NULL, sizeof (dyn_posflag1_buf->buf), vda_alt, NULL, 0, 0,
834734Sab196087 	    MSG_ORIG(MSG_STR_EMPTY), NULL, MSG_ORIG(MSG_STR_EMPTY) };
842352Sab196087 
852352Sab196087 	CONV_EXPN_FIELD_ARG *arg;
861618Srie 
870Sstevel@tonic-gate 	if (flags == 0)
880Sstevel@tonic-gate 		return (MSG_ORIG(MSG_GBL_ZERO));
890Sstevel@tonic-gate 
905088Sab196087 	arg = (CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_DUMP) ?
915088Sab196087 	    &conv_arg_alt : &conv_arg;
924734Sab196087 	arg->buf = dyn_posflag1_buf->buf;
932352Sab196087 	arg->oflags = arg->rflags = flags;
945088Sab196087 	(void) conv_expn_field(arg, fmt_flags);
950Sstevel@tonic-gate 
964734Sab196087 	return ((const char *)dyn_posflag1_buf);
970Sstevel@tonic-gate }
980Sstevel@tonic-gate 
992352Sab196087 #define	FLAGSZ	CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
1002352Sab196087 		MSG_DF_ORIGIN_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1012352Sab196087 		MSG_DF_SYMBOLIC_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1022352Sab196087 		MSG_DF_TEXTREL_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1032352Sab196087 		MSG_DF_BIND_NOW_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1042352Sab196087 		MSG_DF_STATIC_TLS_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1054734Sab196087 		CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
1064734Sab196087 
1074734Sab196087 /*
1084734Sab196087  * Ensure that Conv_dyn_flag_buf_t is large enough:
1094734Sab196087  *
1104734Sab196087  * FLAGSZ is the real minimum size of the buffer required by conv_dyn_flag().
1114734Sab196087  * However, Conv_dyn_flag_buf_t uses CONV_DYN_FLAG_BUFSIZE to set the
1124734Sab196087  * buffer size. We do things this way because the definition of FLAGSZ uses
1134734Sab196087  * information that is not available in the environment of other programs
1144734Sab196087  * that include the conv.h header file.
1154734Sab196087  */
1165152Sab196087 #if (CONV_DYN_FLAG_BUFSIZE != FLAGSZ) && !defined(__lint)
1175152Sab196087 #define	REPORT_BUFSIZE FLAGSZ
1185152Sab196087 #include "report_bufsize.h"
1195152Sab196087 #error "CONV_DYN_FLAG_BUFSIZE does not match FLAGSZ"
1204734Sab196087 #endif
1210Sstevel@tonic-gate const char *
1225088Sab196087 conv_dyn_flag(Xword flags, Conv_fmt_flags_t fmt_flags,
1235088Sab196087     Conv_dyn_flag_buf_t *dyn_flag_buf)
1240Sstevel@tonic-gate {
1251618Srie 	static Val_desc vda[] = {
1261618Srie 		{ DF_ORIGIN,		MSG_ORIG(MSG_DF_ORIGIN) },
1271618Srie 		{ DF_SYMBOLIC,		MSG_ORIG(MSG_DF_SYMBOLIC) },
1281618Srie 		{ DF_TEXTREL,		MSG_ORIG(MSG_DF_TEXTREL) },
1291618Srie 		{ DF_BIND_NOW,		MSG_ORIG(MSG_DF_BIND_NOW) },
1301618Srie 		{ DF_STATIC_TLS,	MSG_ORIG(MSG_DF_STATIC_TLS) },
1311618Srie 		{ 0,			0 }
1321618Srie 	};
1334734Sab196087 	static CONV_EXPN_FIELD_ARG conv_arg = {
1344734Sab196087 	    NULL, sizeof (dyn_flag_buf->buf), vda };
1351618Srie 
1360Sstevel@tonic-gate 	if (flags == 0)
1370Sstevel@tonic-gate 		return (MSG_ORIG(MSG_GBL_ZERO));
1380Sstevel@tonic-gate 
1394734Sab196087 	conv_arg.buf = dyn_flag_buf->buf;
1402352Sab196087 	conv_arg.oflags = conv_arg.rflags = flags;
1415088Sab196087 	if (CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_DUMP) {
1422352Sab196087 		conv_arg.prefix = conv_arg.suffix = MSG_ORIG(MSG_STR_EMPTY);
1432352Sab196087 	} else {
1442352Sab196087 		conv_arg.prefix = conv_arg.suffix = NULL;
1452352Sab196087 	}
1465088Sab196087 	(void) conv_expn_field(&conv_arg, fmt_flags);
1470Sstevel@tonic-gate 
1484734Sab196087 	return ((const char *)dyn_flag_buf->buf);
1490Sstevel@tonic-gate }
1500Sstevel@tonic-gate 
1512352Sab196087 #define	FLAG1SZ	CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
1522352Sab196087 		MSG_DF1_NOW_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1532352Sab196087 		MSG_DF1_GLOBAL_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1542352Sab196087 		MSG_DF1_GROUP_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1552352Sab196087 		MSG_DF1_NODELETE_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1562352Sab196087 		MSG_DF1_LOADFLTR_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1572352Sab196087 		MSG_DF1_INITFIRST_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1582352Sab196087 		MSG_DF1_NOOPEN_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1592352Sab196087 		MSG_DF1_ORIGIN_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1602352Sab196087 		MSG_DF1_DIRECT_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1612352Sab196087 		MSG_DF1_TRANS_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1622352Sab196087 		MSG_DF1_INTERPOSE_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1632352Sab196087 		MSG_DF1_NODEFLIB_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1642352Sab196087 		MSG_DF1_NODUMP_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1652352Sab196087 		MSG_DF1_CONFALT_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1662352Sab196087 		MSG_DF1_ENDFILTEE_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1672352Sab196087 		MSG_DF1_DISPRELPND_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1682352Sab196087 		MSG_DF1_DISPRELDNE_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1692352Sab196087 		MSG_DF1_NODIRECT_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1702352Sab196087 		MSG_DF1_IGNMULDEF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1712352Sab196087 		MSG_DF1_NOKSYMS_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1723466Srie 		MSG_DF1_NOHDR_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1732352Sab196087 		MSG_DF1_NORELOC_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1743466Srie 		MSG_DF1_SYMINTPOSE_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1754679Srie 		MSG_DF1_GLOBAUDIT_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1765220Srie 		MSG_DF1_SINGLETON_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
1774734Sab196087 		CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
1784734Sab196087 
1794734Sab196087 /*
1804734Sab196087  * Ensure that Conv_dyn_flag1_buf_t is large enough:
1814734Sab196087  *
1824734Sab196087  * FLAG1SZ is the real minimum size of the buffer required by conv_dyn_flag1().
1834734Sab196087  * However, Conv_dyn_flag1_buf_t uses CONV_DYN_FLAG1_BUFSIZE to set the
1844734Sab196087  * buffer size. We do things this way because the definition of FLAG1SZ uses
1854734Sab196087  * information that is not available in the environment of other programs
1864734Sab196087  * that include the conv.h header file.
1874734Sab196087  */
1885152Sab196087 #if (CONV_DYN_FLAG1_BUFSIZE != FLAG1SZ) && !defined(__lint)
1895152Sab196087 #define	REPORT_BUFSIZE FLAG1SZ
1905152Sab196087 #include "report_bufsize.h"
1915152Sab196087 #error "CONV_DYN_FLAG1_BUFSIZE does not match FLAG1SZ"
1924734Sab196087 #endif
1930Sstevel@tonic-gate 
1940Sstevel@tonic-gate const char *
1955088Sab196087 conv_dyn_flag1(Xword flags, Conv_fmt_flags_t fmt_flags,
1965088Sab196087     Conv_dyn_flag1_buf_t *dyn_flag1_buf)
1970Sstevel@tonic-gate {
1981618Srie 	static Val_desc vda[] = {
1992352Sab196087 		{ DF_1_NOW,		MSG_ORIG(MSG_DF1_NOW) },
2001618Srie 		{ DF_1_GLOBAL,		MSG_ORIG(MSG_DF1_GLOBAL) },
2011618Srie 		{ DF_1_GROUP,		MSG_ORIG(MSG_DF1_GROUP) },
2021618Srie 		{ DF_1_NODELETE,	MSG_ORIG(MSG_DF1_NODELETE) },
2031618Srie 		{ DF_1_LOADFLTR,	MSG_ORIG(MSG_DF1_LOADFLTR) },
2041618Srie 		{ DF_1_INITFIRST,	MSG_ORIG(MSG_DF1_INITFIRST) },
2051618Srie 		{ DF_1_NOOPEN,		MSG_ORIG(MSG_DF1_NOOPEN) },
2061618Srie 		{ DF_1_ORIGIN,		MSG_ORIG(MSG_DF1_ORIGIN) },
2071618Srie 		{ DF_1_DIRECT,		MSG_ORIG(MSG_DF1_DIRECT) },
2081618Srie 		{ DF_1_TRANS,		MSG_ORIG(MSG_DF1_TRANS) },
2091618Srie 		{ DF_1_INTERPOSE,	MSG_ORIG(MSG_DF1_INTERPOSE) },
2101618Srie 		{ DF_1_NODEFLIB,	MSG_ORIG(MSG_DF1_NODEFLIB) },
2111618Srie 		{ DF_1_NODUMP,		MSG_ORIG(MSG_DF1_NODUMP) },
2121618Srie 		{ DF_1_CONFALT,		MSG_ORIG(MSG_DF1_CONFALT) },
2131618Srie 		{ DF_1_ENDFILTEE,	MSG_ORIG(MSG_DF1_ENDFILTEE) },
2143850Sab196087 		{ DF_1_DISPRELDNE,	MSG_ORIG(MSG_DF1_DISPRELDNE) },
2151618Srie 		{ DF_1_DISPRELPND,	MSG_ORIG(MSG_DF1_DISPRELPND) },
2161618Srie 		{ DF_1_NODIRECT,	MSG_ORIG(MSG_DF1_NODIRECT) },
2171618Srie 		{ DF_1_IGNMULDEF,	MSG_ORIG(MSG_DF1_IGNMULDEF) },
2181618Srie 		{ DF_1_NOKSYMS,		MSG_ORIG(MSG_DF1_NOKSYMS) },
2193466Srie 		{ DF_1_NOHDR,		MSG_ORIG(MSG_DF1_NOHDR) },
2203850Sab196087 		{ DF_1_EDITED,		MSG_ORIG(MSG_DF1_EDITED) },
2211618Srie 		{ DF_1_NORELOC,		MSG_ORIG(MSG_DF1_NORELOC) },
2223466Srie 		{ DF_1_SYMINTPOSE,	MSG_ORIG(MSG_DF1_SYMINTPOSE) },
2234679Srie 		{ DF_1_GLOBAUDIT,	MSG_ORIG(MSG_DF1_GLOBAUDIT) },
2245220Srie 		{ DF_1_SINGLETON,	MSG_ORIG(MSG_DF1_SINGLETON) },
2251618Srie 		{ 0,			0 }
2261618Srie 	};
2274734Sab196087 	static CONV_EXPN_FIELD_ARG conv_arg = {
2284734Sab196087 	    NULL, sizeof (dyn_flag1_buf->buf), vda };
2290Sstevel@tonic-gate 
2300Sstevel@tonic-gate 	if (flags == 0)
2310Sstevel@tonic-gate 		return (MSG_ORIG(MSG_GBL_ZERO));
2320Sstevel@tonic-gate 
2332352Sab196087 	conv_arg.oflags = conv_arg.rflags = flags;
2344734Sab196087 	conv_arg.buf = dyn_flag1_buf->buf;
2355088Sab196087 	(void) conv_expn_field(&conv_arg, fmt_flags);
2360Sstevel@tonic-gate 
2374734Sab196087 	return ((const char *)dyn_flag1_buf->buf);
2380Sstevel@tonic-gate }
2390Sstevel@tonic-gate 
2402352Sab196087 #define	FEATSZ	CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
2412352Sab196087 		MSG_DTF_PARINIT_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
2422352Sab196087 		MSG_DTF_CONFEXP_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
2434734Sab196087 		CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
2444734Sab196087 
2454734Sab196087 /*
2464734Sab196087  * Ensure that Conv_dyn_feature1_buf_t is large enough:
2474734Sab196087  *
2484734Sab196087  * FEATSZ is the real min size of the buffer required by conv_dyn_feature1().
2494734Sab196087  * However, Conv_dyn_feature1_buf_t uses CONV_DYN_FEATURE1_BUFSIZE to set the
2504734Sab196087  * buffer size. We do things this way because the definition of FEATSZ uses
2514734Sab196087  * information that is not available in the environment of other programs
2524734Sab196087  * that include the conv.h header file.
2534734Sab196087  */
2545152Sab196087 #if (CONV_DYN_FEATURE1_BUFSIZE != FEATSZ) && !defined(__lint)
2555152Sab196087 #define	REPORT_BUFSIZE FEATSZ
2565152Sab196087 #include "report_bufsize.h"
2575152Sab196087 #error "CONV_DYN_FEATURE1_BUFSIZE does not match FEATSZ"
2584734Sab196087 #endif
2590Sstevel@tonic-gate 
2600Sstevel@tonic-gate const char *
2615088Sab196087 conv_dyn_feature1(Xword flags, Conv_fmt_flags_t fmt_flags,
2624734Sab196087     Conv_dyn_feature1_buf_t *dyn_feature1_buf)
2630Sstevel@tonic-gate {
2641618Srie 	static Val_desc vda[] = {
2651618Srie 		{ DTF_1_PARINIT,	MSG_ORIG(MSG_DTF_PARINIT) },
2661618Srie 		{ DTF_1_CONFEXP,	MSG_ORIG(MSG_DTF_CONFEXP) },
2671618Srie 		{ 0,			0 }
2681618Srie 	};
2694734Sab196087 	static CONV_EXPN_FIELD_ARG conv_arg = {
2704734Sab196087 	    NULL, sizeof (dyn_feature1_buf->buf), vda };
2710Sstevel@tonic-gate 
2720Sstevel@tonic-gate 	if (flags == 0)
2730Sstevel@tonic-gate 		return (MSG_ORIG(MSG_GBL_ZERO));
2740Sstevel@tonic-gate 
2754734Sab196087 	conv_arg.buf = dyn_feature1_buf->buf;
2762352Sab196087 	conv_arg.oflags = conv_arg.rflags = flags;
2775088Sab196087 	if (CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_DUMP) {
2782352Sab196087 		conv_arg.prefix = conv_arg.suffix = MSG_ORIG(MSG_STR_EMPTY);
2792352Sab196087 	} else {
2802352Sab196087 		conv_arg.prefix = conv_arg.suffix = NULL;
2812352Sab196087 	}
2825088Sab196087 	(void) conv_expn_field(&conv_arg, fmt_flags);
2830Sstevel@tonic-gate 
2844734Sab196087 	return ((const char *)dyn_feature1_buf->buf);
2850Sstevel@tonic-gate }
2860Sstevel@tonic-gate 
2870Sstevel@tonic-gate const char *
2885088Sab196087 conv_dyn_tag(Xword tag, Half mach, Conv_fmt_flags_t fmt_flags,
2895088Sab196087     Conv_inv_buf_t *inv_buf)
2900Sstevel@tonic-gate {
2913492Sab196087 	/*
2923492Sab196087 	 * Dynamic tag values are sparse, cover a wide range, and have
2933492Sab196087 	 * holes. To handle this efficiently, we fall through a series
2943492Sab196087 	 * of tests below, in increasing tag order, returning at the first
2953492Sab196087 	 * match.
2963492Sab196087 	 *
2973492Sab196087 	 * If we fall all the way to the end, the tag is unknown,
2983492Sab196087 	 * and its numeric value is printed.
2993492Sab196087 	 */
3003492Sab196087 
3013492Sab196087 	/*
3023492Sab196087 	 * Most of the tag values are clustered in contiguous ranges.
3033492Sab196087 	 * Each contiguous range of defined values is handled with
3043492Sab196087 	 * an array that contains the message index corresponding to
3053492Sab196087 	 * each value in that range. The DYN_RANGE macro checks the
3063492Sab196087 	 * tag value against range of values starting at _start_tag.
3073492Sab196087 	 * If there is a match, the index of the appropriate name is
3083492Sab196087 	 * pulled from _array and returned to the caller.
3093492Sab196087 	 */
3103492Sab196087 #define	DYN_RANGE(_start_tag, _array) \
3113492Sab196087 	if ((tag >= _start_tag) && (tag < (_start_tag + ARRAY_NELTS(_array)))) \
3123492Sab196087 		return (MSG_ORIG(_array[tag - _start_tag]));
3133492Sab196087 
3143492Sab196087 
3153492Sab196087 	/*
3163492Sab196087 	 * Generic dynamic tags:
3173492Sab196087 	 *	- Note hole between DT_FLAGS and DT_PREINIT_ARRAY
3183492Sab196087 	 *	- The first range has alternative names for dump,
3193492Sab196087 	 *	  requiring a second array.
3203492Sab196087 	 */
3213492Sab196087 	static const Msg	tags_null[] = {
3221618Srie 		MSG_DYN_NULL,		MSG_DYN_NEEDED,
3231618Srie 		MSG_DYN_PLTRELSZ,	MSG_DYN_PLTGOT,
3241618Srie 		MSG_DYN_HASH,		MSG_DYN_STRTAB,
3251618Srie 		MSG_DYN_SYMTAB,		MSG_DYN_RELA,
3261618Srie 		MSG_DYN_RELASZ,		MSG_DYN_RELAENT,
3271618Srie 		MSG_DYN_STRSZ,		MSG_DYN_SYMENT,
3281618Srie 		MSG_DYN_INIT,		MSG_DYN_FINI,
3291618Srie 		MSG_DYN_SONAME,		MSG_DYN_RPATH,
3301618Srie 		MSG_DYN_SYMBOLIC,	MSG_DYN_REL,
3311618Srie 		MSG_DYN_RELSZ,		MSG_DYN_RELENT,
3321618Srie 		MSG_DYN_PLTREL,		MSG_DYN_DEBUG,
3331618Srie 		MSG_DYN_TEXTREL,	MSG_DYN_JMPREL,
3341618Srie 		MSG_DYN_BIND_NOW,	MSG_DYN_INIT_ARRAY,
3351618Srie 		MSG_DYN_FINI_ARRAY,	MSG_DYN_INIT_ARRAYSZ,
3361618Srie 		MSG_DYN_FINI_ARRAYSZ,	MSG_DYN_RUNPATH,
3373492Sab196087 		MSG_DYN_FLAGS
3381618Srie 	};
3393492Sab196087 	static const Msg	tags_null_alt[] = {
3401976Sab196087 		MSG_DYN_NULL,		MSG_DYN_NEEDED,
3411976Sab196087 		MSG_DYN_PLTRELSZ_ALT,	MSG_DYN_PLTGOT,
3421976Sab196087 		MSG_DYN_HASH,		MSG_DYN_STRTAB,
3431976Sab196087 		MSG_DYN_SYMTAB,		MSG_DYN_RELA,
3441976Sab196087 		MSG_DYN_RELASZ,		MSG_DYN_RELAENT,
3451976Sab196087 		MSG_DYN_STRSZ,		MSG_DYN_SYMENT,
3461976Sab196087 		MSG_DYN_INIT,		MSG_DYN_FINI,
3471976Sab196087 		MSG_DYN_SONAME,		MSG_DYN_RPATH,
3481976Sab196087 		MSG_DYN_SYMBOLIC_ALT,	MSG_DYN_REL,
3491976Sab196087 		MSG_DYN_RELSZ,		MSG_DYN_RELENT,
3501976Sab196087 		MSG_DYN_PLTREL,		MSG_DYN_DEBUG,
3511976Sab196087 		MSG_DYN_TEXTREL,	MSG_DYN_JMPREL,
3521976Sab196087 		MSG_DYN_BIND_NOW,	MSG_DYN_INIT_ARRAY,
3531976Sab196087 		MSG_DYN_FINI_ARRAY,	MSG_DYN_INIT_ARRAYSZ,
3541976Sab196087 		MSG_DYN_FINI_ARRAYSZ,	MSG_DYN_RUNPATH,
3553492Sab196087 		MSG_DYN_FLAGS
3563492Sab196087 	};
3573492Sab196087 	static const Msg	tags_preinit_array[] = {
3581976Sab196087 		MSG_DYN_PREINIT_ARRAY,	MSG_DYN_PREINIT_ARRAYSZ
3591976Sab196087 	};
3600Sstevel@tonic-gate 
3613492Sab196087 	/*
362*6206Sab196087 	 * SUNW: DT_LOOS -> DT_HIOS range. Note hole between DT_SUNW_TLSSORTSZ,
363*6206Sab196087 	 * DT_SUNW_STRPAD, and DT_SUNW_LDMACH. We handle the outliers
364*6206Sab196087 	 * separately below as single values.
3653492Sab196087 	 */
3663492Sab196087 	static const Msg	tags_sunw_auxiliary[] = {
3673492Sab196087 		MSG_DYN_SUNW_AUXILIARY,	MSG_DYN_SUNW_RTLDINF,
3683492Sab196087 		MSG_DYN_SUNW_FILTER,	MSG_DYN_SUNW_CAP,
3693492Sab196087 		MSG_DYN_SUNW_SYMTAB,	MSG_DYN_SUNW_SYMSZ,
3703731Srie 		MSG_DYN_SUNW_SORTENT,	MSG_DYN_SUNW_SYMSORT,
3713731Srie 		MSG_DYN_SUNW_SYMSORTSZ,	MSG_DYN_SUNW_TLSSORT,
3723731Srie 		MSG_DYN_SUNW_TLSSORTSZ
3733492Sab196087 	};
3740Sstevel@tonic-gate 
3753492Sab196087 	/*
3763492Sab196087 	 * SUNW: DT_VALRNGLO - DT_VALRNGHI range.
3773492Sab196087 	 */
3783492Sab196087 	static const Msg	tags_checksum[] = {
3793492Sab196087 		MSG_DYN_CHECKSUM,	MSG_DYN_PLTPADSZ,
3803492Sab196087 		MSG_DYN_MOVEENT,	MSG_DYN_MOVESZ,
3813492Sab196087 		MSG_DYN_FEATURE_1,	MSG_DYN_POSFLAG_1,
3823492Sab196087 		MSG_DYN_SYMINSZ,	MSG_DYN_SYMINENT
3833492Sab196087 	};
3843492Sab196087 
3853492Sab196087 	/*
3863492Sab196087 	 * SUNW: DT_ADDRRNGLO - DT_ADDRRNGHI range.
3873492Sab196087 	 */
3883492Sab196087 	static const Msg	tags_config[] = {
3893492Sab196087 		MSG_DYN_CONFIG,		MSG_DYN_DEPAUDIT,
3903492Sab196087 		MSG_DYN_AUDIT,		MSG_DYN_PLTPAD,
3913492Sab196087 		MSG_DYN_MOVETAB,	MSG_DYN_SYMINFO
3923492Sab196087 	};
3930Sstevel@tonic-gate 
3943492Sab196087 	/*
3953492Sab196087 	 * SUNW: generic range. Note hole between DT_VERSYM and DT_RELACOUNT.
3963492Sab196087 	 * We handle DT_VERSYM as a single value below.
3973492Sab196087 	 */
3983492Sab196087 	static const Msg	tags_relacount[] = {
3993492Sab196087 		MSG_DYN_RELACOUNT,	MSG_DYN_RELCOUNT,
4003492Sab196087 		MSG_DYN_FLAGS_1,	MSG_DYN_VERDEF,
4013492Sab196087 		MSG_DYN_VERDEFNUM,	MSG_DYN_VERNEED,
4023492Sab196087 		MSG_DYN_VERNEEDNUM
4033492Sab196087 	};
4043492Sab196087 
4053492Sab196087 	/*
4063492Sab196087 	 * DT_LOPROC - DT_HIPROC range.
4073492Sab196087 	 */
4083492Sab196087 	static const Msg	tags_auxiliary[] = {
4093492Sab196087 		MSG_DYN_AUXILIARY,	MSG_DYN_USED,
4103492Sab196087 		MSG_DYN_FILTER
4113492Sab196087 	};
4123492Sab196087 
4133492Sab196087 
4143492Sab196087 
4150Sstevel@tonic-gate 
4165088Sab196087 	if (tag <= DT_FLAGS) {
4175088Sab196087 		/* use 'dump' style? */
4185088Sab196087 		if (CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_DUMP)
4195088Sab196087 			return (conv_map2str(inv_buf, tag, fmt_flags,
4205088Sab196087 			    ARRAY_NELTS(tags_null_alt), tags_null_alt));
4215088Sab196087 		/* Standard style */
4224734Sab196087 		return (conv_map2str(inv_buf, tag, fmt_flags,
4235088Sab196087 		    ARRAY_NELTS(tags_null), tags_null));
4245088Sab196087 	}
4253492Sab196087 	DYN_RANGE(DT_PREINIT_ARRAY, tags_preinit_array);
4263492Sab196087 	DYN_RANGE(DT_SUNW_AUXILIARY, tags_sunw_auxiliary);
4273850Sab196087 	if (tag == DT_SUNW_STRPAD)
4283850Sab196087 		return (MSG_ORIG(MSG_DYN_SUNW_STRPAD));
429*6206Sab196087 	if (tag == DT_SUNW_LDMACH)
430*6206Sab196087 		return (MSG_ORIG(MSG_DYN_SUNW_LDMACH));
4313492Sab196087 	DYN_RANGE(DT_CHECKSUM, tags_checksum);
4323492Sab196087 	DYN_RANGE(DT_CONFIG, tags_config);
4333492Sab196087 	if (tag == DT_VERSYM)
4343492Sab196087 		return (MSG_ORIG(MSG_DYN_VERSYM));
4353492Sab196087 	DYN_RANGE(DT_RELACOUNT, tags_relacount);
4363492Sab196087 	DYN_RANGE(DT_AUXILIARY, tags_auxiliary);
4370Sstevel@tonic-gate 
4383492Sab196087 	/*
4393492Sab196087 	 * SUNW: machine specific range.
4403492Sab196087 	 */
4413492Sab196087 	if (((mach == EM_SPARC) || (mach == EM_SPARCV9) ||
4423492Sab196087 	    (mach == EM_SPARC32PLUS)) && (tag == DT_SPARC_REGISTER))
4433492Sab196087 		/* this is so x86 can display a sparc binary */
4443492Sab196087 		return (MSG_ORIG(MSG_DYN_REGISTER));
4453492Sab196087 
4463492Sab196087 	if (tag == DT_DEPRECATED_SPARC_REGISTER)
4473492Sab196087 		return (MSG_ORIG(MSG_DYN_REGISTER));
4483492Sab196087 
4493492Sab196087 	/* Unknown item */
4504734Sab196087 	return (conv_invalid_val(inv_buf, tag, fmt_flags));
4513492Sab196087 
4523492Sab196087 #undef DYN_RANGE
4530Sstevel@tonic-gate }
454280Srie 
4552352Sab196087 #define	BINDTSZ	CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
4562352Sab196087 		MSG_BND_NEEDED_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
4572352Sab196087 		MSG_BND_REFER_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
4582352Sab196087 		MSG_BND_FILTER_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
4594734Sab196087 		CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
4604734Sab196087 
4614734Sab196087 /*
4624734Sab196087  * Ensure that Conv_bnd_type_buf_t is large enough:
4634734Sab196087  *
4644734Sab196087  * BINDTSZ is the real minimum size of the buffer required by conv_bnd_type().
4654734Sab196087  * However, Conv_bnd_type_buf_t uses CONV_BND_TYPE_BUFSIZE to set the
4664734Sab196087  * buffer size. We do things this way because the definition of BINDTSZ uses
4674734Sab196087  * information that is not available in the environment of other programs
4684734Sab196087  * that include the conv.h header file.
4694734Sab196087  */
4705152Sab196087 #if (CONV_BND_TYPE_BUFSIZE != BINDTSZ) && !defined(__lint)
4715152Sab196087 #define	REPORT_BUFSIZE BINDTSZ
4725152Sab196087 #include "report_bufsize.h"
4735152Sab196087 #error "CONV_BND_TYPE_BUFSIZE does not match BINDTSZ"
4744734Sab196087 #endif
475280Srie 
476280Srie const char *
4774734Sab196087 conv_bnd_type(uint_t flags, Conv_bnd_type_buf_t *bnd_type_buf)
478280Srie {
4791618Srie 	static Val_desc vda[] = {
4801618Srie 		{ BND_NEEDED,		MSG_ORIG(MSG_BND_NEEDED) },
4811618Srie 		{ BND_REFER,		MSG_ORIG(MSG_BND_REFER) },
4821618Srie 		{ BND_FILTER,		MSG_ORIG(MSG_BND_FILTER) },
4831618Srie 		{ 0,			0 }
4841618Srie 	};
4854734Sab196087 	static CONV_EXPN_FIELD_ARG conv_arg = {
4864734Sab196087 	    NULL, sizeof (bnd_type_buf->buf), vda };
487280Srie 
4881618Srie 	if (flags == 0)
4891618Srie 		return (MSG_ORIG(MSG_STR_EMPTY));
490280Srie 
4914734Sab196087 	conv_arg.buf = bnd_type_buf->buf;
4922352Sab196087 	conv_arg.oflags = conv_arg.rflags = flags;
4935088Sab196087 	(void) conv_expn_field(&conv_arg, 0);
4941618Srie 
4954734Sab196087 	return ((const char *)bnd_type_buf->buf);
496280Srie }
497280Srie 
4981824Srie /*
4991824Srie  * Note, conv_bnd_obj() is called with either:
5001824Srie  *	LML_FLG_OBJADDED (possibly with LML_FLG_OBJREEVAL added), or
5011824Srie  *	LML_FLG_OBJDELETED, or
5021824Srie  *	LML_FLG_ATEXIT.
5031824Srie  */
5042352Sab196087 #define	BINDOSZ	CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
5052352Sab196087 		MSG_BND_ADDED_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
5062352Sab196087 		MSG_BND_REEVAL_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
5074734Sab196087 		CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
5084734Sab196087 
5094734Sab196087 /*
5104734Sab196087  * Ensure that Conv_bnd_obj_buf_t is large enough:
5114734Sab196087  *
5124734Sab196087  * BINDOSZ is the real minimum size of the buffer required by conv_bnd_obj().
5134734Sab196087  * However, Conv_bnd_obj_buf_t uses CONV_BND_OBJ_BUFSIZE to set the
5144734Sab196087  * buffer size. We do things this way because the definition of BINDOSZ uses
5154734Sab196087  * information that is not available in the environment of other programs
5164734Sab196087  * that include the conv.h header file.
5174734Sab196087  */
5185152Sab196087 #if (CONV_BND_OBJ_BUFSIZE != BINDOSZ) && !defined(__lint)
5195152Sab196087 #define	REPORT_BUFSIZE BINDOSZ
5205152Sab196087 #include "report_bufsize.h"
5215152Sab196087 #error "CONV_BND_OBJ_BUFSIZE does not match BINDOSZ"
5224734Sab196087 #endif
523280Srie 
524280Srie const char *
5254734Sab196087 conv_bnd_obj(uint_t flags, Conv_bnd_obj_buf_t *bnd_obj_buf)
526280Srie {
5271618Srie 	static Val_desc vda[] = {
5281618Srie 		{ LML_FLG_OBJADDED,	MSG_ORIG(MSG_BND_ADDED) },
5291618Srie 		{ LML_FLG_OBJREEVAL,	MSG_ORIG(MSG_BND_REEVAL) },
5301618Srie 		{ LML_FLG_OBJDELETED,	MSG_ORIG(MSG_BND_DELETED) },
5311618Srie 		{ LML_FLG_ATEXIT,	MSG_ORIG(MSG_BND_ATEXIT) },
5321618Srie 		{ 0,			0 }
5331618Srie 	};
5344734Sab196087 	static CONV_EXPN_FIELD_ARG conv_arg = {
5354734Sab196087 	    NULL, sizeof (bnd_obj_buf->buf), vda };
5361618Srie 
5371824Srie 	if ((flags & (LML_FLG_OBJADDED | LML_FLG_OBJREEVAL |
5381824Srie 	    LML_FLG_OBJDELETED | LML_FLG_ATEXIT)) == 0)
5391824Srie 		return (MSG_ORIG(MSG_BND_REVISIT));
540280Srie 
541280Srie 	/*
5421618Srie 	 * Note, we're not worried about unknown flags for this family, only
5432352Sab196087 	 * the selected flags are of interest, so we leave conv_arg.rflags
5442352Sab196087 	 * set to 0.
545280Srie 	 */
5464734Sab196087 	conv_arg.buf = bnd_obj_buf->buf;
5472352Sab196087 	conv_arg.oflags = flags;
5485088Sab196087 	(void) conv_expn_field(&conv_arg, 0);
549280Srie 
5504734Sab196087 	return ((const char *)bnd_obj_buf->buf);
551280Srie }
552