Home | History | Annotate | Download | only in common
      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 2009 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 /*
     28  * String conversion routine for .dynamic tag entries.
     29  */
     30 #include	<stdio.h>
     31 #include	<string.h>
     32 #include	<sys/elf_SPARC.h>
     33 #include	"rtld.h"
     34 #include	"_conv.h"
     35 #include	"dynamic_msg.h"
     36 
     37 
     38 
     39 const Val_desc *
     40 conv_dyn_posflag1_strings(Conv_fmt_flags_t fmt_flags)
     41 {
     42 #define	POSSZ	CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
     43 	MSG_DF_P1_LAZYLOAD_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
     44 	MSG_DF_P1_GROUPPERM_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
     45 	CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
     46 
     47 	/*
     48 	 * Ensure that Conv_dyn_posflag1_buf_t is large enough:
     49 	 *
     50 	 * POSSZ is the real minimum size of the buffer required by
     51 	 * conv_dyn_posflag1(). However, Conv_dyn_posflag1_buf_t uses
     52 	 * CONV_DYN_POSFLAG1_BUFSIZE to set the buffer size. We do things
     53 	 * this way because the definition of POSSZ uses
     54 	 * information that is not available in the environment of other
     55 	 * programs that include the conv.h header file.
     56 	 */
     57 #if (CONV_DYN_POSFLAG1_BUFSIZE != POSSZ) && !defined(__lint)
     58 #define	REPORT_BUFSIZE POSSZ
     59 #include "report_bufsize.h"
     60 #error "CONV_DYN_POSFLAG1_BUFSIZE does not match POSSZ"
     61 #endif
     62 
     63 	static const Val_desc vda_def[] = {
     64 		{ DF_P1_LAZYLOAD,	MSG_DF_P1_LAZYLOAD_DEF },
     65 		{ DF_P1_GROUPPERM,	MSG_DF_P1_GROUPPERM_CFNP },
     66 		{ 0,			0 }
     67 	};
     68 	static const Val_desc vda_cf[] = {
     69 		{ DF_P1_LAZYLOAD,	MSG_DF_P1_LAZYLOAD_CF },
     70 		{ DF_P1_GROUPPERM,	MSG_DF_P1_GROUPPERM_CF },
     71 		{ 0,			0 }
     72 	};
     73 	static const Val_desc vda_cfnp[] = {
     74 		{ DF_P1_LAZYLOAD,	MSG_DF_P1_LAZYLOAD_CFNP },
     75 		{ DF_P1_GROUPPERM,	MSG_DF_P1_GROUPPERM_CFNP },
     76 		{ 0,			0 }
     77 	};
     78 	static const Val_desc vda_nf[] = {
     79 		{ DF_P1_LAZYLOAD,	MSG_DF_P1_LAZYLOAD_NF },
     80 		{ DF_P1_GROUPPERM,	MSG_DF_P1_GROUPPERM_NF },
     81 		{ 0,			0 }
     82 	};
     83 
     84 	switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
     85 	case CONV_FMT_ALT_DUMP:
     86 	case CONV_FMT_ALT_CFNP:
     87 		return (vda_cfnp);
     88 	case CONV_FMT_ALT_CF:
     89 		return (vda_cf);
     90 	case CONV_FMT_ALT_NF:
     91 		return (vda_nf);
     92 	}
     93 
     94 	return (vda_def);
     95 }
     96 
     97 conv_iter_ret_t
     98 conv_iter_dyn_posflag1(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func,
     99     void *uvalue)
    100 {
    101 	return (conv_iter_vd(conv_dyn_posflag1_strings(fmt_flags),
    102 	    func, uvalue));
    103 }
    104 
    105 const Val_desc *
    106 conv_dyn_flag_strings(Conv_fmt_flags_t fmt_flags)
    107 {
    108 #define	FLAGSZ	CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
    109 	MSG_DF_ORIGIN_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    110 	MSG_DF_SYMBOLIC_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    111 	MSG_DF_TEXTREL_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    112 	MSG_DF_BIND_NOW_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    113 	MSG_DF_STATIC_TLS_CF_SIZE 	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    114 	CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
    115 
    116 	/*
    117 	 * Ensure that Conv_dyn_flag_buf_t is large enough:
    118 	 *
    119 	 * FLAGSZ is the real minimum size of the buffer required by
    120 	 * conv_dyn_flag(). However, Conv_dyn_flag_buf_t uses
    121 	 * CONV_DYN_FLAG_BUFSIZE to set the buffer size. We do things this
    122 	 * way because the definition of FLAGSZ uses information that is not
    123 	 * available in the environment of other programs that include the
    124 	 * conv.h header file.
    125 	 */
    126 #if (CONV_DYN_FLAG_BUFSIZE != FLAGSZ) && !defined(__lint)
    127 #define	REPORT_BUFSIZE FLAGSZ
    128 #include "report_bufsize.h"
    129 #error "CONV_DYN_FLAG_BUFSIZE does not match FLAGSZ"
    130 #endif
    131 
    132 	static const Val_desc vda_cf[] = {
    133 		{ DF_ORIGIN,		MSG_DF_ORIGIN_CF },
    134 		{ DF_SYMBOLIC,		MSG_DF_SYMBOLIC_CF },
    135 		{ DF_TEXTREL,		MSG_DF_TEXTREL_CF },
    136 		{ DF_BIND_NOW,		MSG_DF_BIND_NOW_CF },
    137 		{ DF_STATIC_TLS,	MSG_DF_STATIC_TLS_CF },
    138 		{ 0 }
    139 	};
    140 	static const Val_desc vda_cfnp[] = {
    141 		{ DF_ORIGIN,		MSG_DF_ORIGIN_CFNP },
    142 		{ DF_SYMBOLIC,		MSG_DF_SYMBOLIC_CFNP },
    143 		{ DF_TEXTREL,		MSG_DF_TEXTREL_CFNP },
    144 		{ DF_BIND_NOW,		MSG_DF_BIND_NOW_CFNP },
    145 		{ DF_STATIC_TLS,	MSG_DF_STATIC_TLS_CFNP },
    146 		{ 0 }
    147 	};
    148 	static const Val_desc vda_nf[] = {
    149 		{ DF_ORIGIN,		MSG_DF_ORIGIN_NF },
    150 		{ DF_SYMBOLIC,		MSG_DF_SYMBOLIC_NF },
    151 		{ DF_TEXTREL,		MSG_DF_TEXTREL_NF },
    152 		{ DF_BIND_NOW,		MSG_DF_BIND_NOW_NF },
    153 		{ DF_STATIC_TLS,	MSG_DF_STATIC_TLS_NF },
    154 		{ 0 }
    155 	};
    156 
    157 	switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
    158 	case CONV_FMT_ALT_CF:
    159 		return (vda_cf);
    160 	case CONV_FMT_ALT_NF:
    161 		return (vda_nf);
    162 	}
    163 
    164 	return (vda_cfnp);
    165 }
    166 
    167 conv_iter_ret_t
    168 conv_iter_dyn_flag(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func,
    169     void *uvalue)
    170 {
    171 	return (conv_iter_vd(conv_dyn_flag_strings(fmt_flags), func, uvalue));
    172 }
    173 
    174 const Val_desc *
    175 conv_dyn_flag1_strings(Conv_fmt_flags_t fmt_flags)
    176 {
    177 #define	FLAG1SZ	CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
    178 	MSG_DF_1_NOW_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    179 	MSG_DF_1_GLOBAL_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    180 	MSG_DF_1_GROUP_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    181 	MSG_DF_1_NODELETE_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    182 	MSG_DF_1_LOADFLTR_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    183 	MSG_DF_1_INITFIRST_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    184 	MSG_DF_1_NOOPEN_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    185 	MSG_DF_1_ORIGIN_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    186 	MSG_DF_1_DIRECT_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    187 	MSG_DF_1_TRANS_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    188 	MSG_DF_1_INTERPOSE_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    189 	MSG_DF_1_NODEFLIB_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    190 	MSG_DF_1_NODUMP_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    191 	MSG_DF_1_CONFALT_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    192 	MSG_DF_1_ENDFILTEE_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    193 	MSG_DF_1_DISPRELPND_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    194 	MSG_DF_1_DISPRELDNE_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    195 	MSG_DF_1_NODIRECT_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    196 	MSG_DF_1_IGNMULDEF_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    197 	MSG_DF_1_NOKSYMS_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    198 	MSG_DF_1_NOHDR_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    199 	MSG_DF_1_NORELOC_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    200 	MSG_DF_1_SYMINTPOSE_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    201 	MSG_DF_1_GLOBAUDIT_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    202 	MSG_DF_1_SINGLETON_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    203 	CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
    204 
    205 	/*
    206 	 * Ensure that Conv_dyn_flag1_buf_t is large enough:
    207 	 *
    208 	 * FLAG1SZ is the real minimum size of the buffer required by
    209 	 * conv_dyn_flag1(). However, Conv_dyn_flag1_buf_t uses
    210 	 * CONV_DYN_FLAG1_BUFSIZE to set the buffer size. We do things this
    211 	 * way because the definition of FLAG1SZ uses information that is not
    212 	 * available in the environment of other programs that include the
    213 	 * conv.h header file.
    214 	 */
    215 #if (CONV_DYN_FLAG1_BUFSIZE != FLAG1SZ) && !defined(__lint)
    216 #define	REPORT_BUFSIZE FLAG1SZ
    217 #include "report_bufsize.h"
    218 #error "CONV_DYN_FLAG1_BUFSIZE does not match FLAG1SZ"
    219 #endif
    220 
    221 	static const Val_desc vda_def[] = {
    222 		{ DF_1_NOW,		MSG_DF_1_NOW_CFNP },
    223 		{ DF_1_GLOBAL,		MSG_DF_1_GLOBAL_CFNP },
    224 		{ DF_1_GROUP,		MSG_DF_1_GROUP_CFNP },
    225 		{ DF_1_NODELETE,	MSG_DF_1_NODELETE_CFNP },
    226 		{ DF_1_LOADFLTR,	MSG_DF_1_LOADFLTR_CFNP },
    227 		{ DF_1_INITFIRST,	MSG_DF_1_INITFIRST_CFNP },
    228 		{ DF_1_NOOPEN,		MSG_DF_1_NOOPEN_CFNP },
    229 		{ DF_1_ORIGIN,		MSG_DF_1_ORIGIN_CFNP },
    230 		{ DF_1_DIRECT,		MSG_DF_1_DIRECT_CFNP },
    231 		{ DF_1_TRANS,		MSG_DF_1_TRANS_CFNP },
    232 		{ DF_1_INTERPOSE,	MSG_DF_1_INTERPOSE_DEF },
    233 		{ DF_1_NODEFLIB,	MSG_DF_1_NODEFLIB_CFNP },
    234 		{ DF_1_NODUMP,		MSG_DF_1_NODUMP_CFNP },
    235 		{ DF_1_CONFALT,		MSG_DF_1_CONFALT_CFNP },
    236 		{ DF_1_ENDFILTEE,	MSG_DF_1_ENDFILTEE_CFNP },
    237 		{ DF_1_DISPRELDNE,	MSG_DF_1_DISPRELDNE_DEF },
    238 		{ DF_1_DISPRELPND,	MSG_DF_1_DISPRELPND_DEF },
    239 		{ DF_1_NODIRECT,	MSG_DF_1_NODIRECT_CFNP },
    240 		{ DF_1_IGNMULDEF,	MSG_DF_1_IGNMULDEF_DEF },
    241 		{ DF_1_NOKSYMS,		MSG_DF_1_NOKSYMS_CFNP },
    242 		{ DF_1_NOHDR,		MSG_DF_1_NOHDR_CFNP },
    243 		{ DF_1_EDITED,		MSG_DF_1_EDITED_CFNP },
    244 		{ DF_1_NORELOC,		MSG_DF_1_NORELOC_CFNP },
    245 		{ DF_1_SYMINTPOSE,	MSG_DF_1_SYMINTPOSE_DEF },
    246 		{ DF_1_GLOBAUDIT,	MSG_DF_1_GLOBAUDIT_DEF },
    247 		{ DF_1_SINGLETON,	MSG_DF_1_SINGLETON_DEF },
    248 		{ 0,			0 }
    249 	};
    250 	static const Val_desc vda_cf[] = {
    251 		{ DF_1_NOW,		MSG_DF_1_NOW_CF },
    252 		{ DF_1_GLOBAL,		MSG_DF_1_GLOBAL_CF },
    253 		{ DF_1_GROUP,		MSG_DF_1_GROUP_CF },
    254 		{ DF_1_NODELETE,	MSG_DF_1_NODELETE_CF },
    255 		{ DF_1_LOADFLTR,	MSG_DF_1_LOADFLTR_CF },
    256 		{ DF_1_INITFIRST,	MSG_DF_1_INITFIRST_CF },
    257 		{ DF_1_NOOPEN,		MSG_DF_1_NOOPEN_CF },
    258 		{ DF_1_ORIGIN,		MSG_DF_1_ORIGIN_CF },
    259 		{ DF_1_DIRECT,		MSG_DF_1_DIRECT_CF },
    260 		{ DF_1_TRANS,		MSG_DF_1_TRANS_CF },
    261 		{ DF_1_INTERPOSE,	MSG_DF_1_INTERPOSE_CF },
    262 		{ DF_1_NODEFLIB,	MSG_DF_1_NODEFLIB_CF },
    263 		{ DF_1_NODUMP,		MSG_DF_1_NODUMP_CF },
    264 		{ DF_1_CONFALT,		MSG_DF_1_CONFALT_CF },
    265 		{ DF_1_ENDFILTEE,	MSG_DF_1_ENDFILTEE_CF },
    266 		{ DF_1_DISPRELDNE,	MSG_DF_1_DISPRELDNE_CF },
    267 		{ DF_1_DISPRELPND,	MSG_DF_1_DISPRELPND_CF },
    268 		{ DF_1_NODIRECT,	MSG_DF_1_NODIRECT_CF },
    269 		{ DF_1_IGNMULDEF,	MSG_DF_1_IGNMULDEF_CF },
    270 		{ DF_1_NOKSYMS,		MSG_DF_1_NOKSYMS_CF },
    271 		{ DF_1_NOHDR,		MSG_DF_1_NOHDR_CF },
    272 		{ DF_1_EDITED,		MSG_DF_1_EDITED_CF },
    273 		{ DF_1_NORELOC,		MSG_DF_1_NORELOC_CF },
    274 		{ DF_1_SYMINTPOSE,	MSG_DF_1_SYMINTPOSE_CF },
    275 		{ DF_1_GLOBAUDIT,	MSG_DF_1_GLOBAUDIT_CF },
    276 		{ DF_1_SINGLETON,	MSG_DF_1_SINGLETON_CF },
    277 		{ 0,			0 }
    278 	};
    279 	static const Val_desc vda_cfnp[] = {
    280 		{ DF_1_NOW,		MSG_DF_1_NOW_CFNP },
    281 		{ DF_1_GLOBAL,		MSG_DF_1_GLOBAL_CFNP },
    282 		{ DF_1_GROUP,		MSG_DF_1_GROUP_CFNP },
    283 		{ DF_1_NODELETE,	MSG_DF_1_NODELETE_CFNP },
    284 		{ DF_1_LOADFLTR,	MSG_DF_1_LOADFLTR_CFNP },
    285 		{ DF_1_INITFIRST,	MSG_DF_1_INITFIRST_CFNP },
    286 		{ DF_1_NOOPEN,		MSG_DF_1_NOOPEN_CFNP },
    287 		{ DF_1_ORIGIN,		MSG_DF_1_ORIGIN_CFNP },
    288 		{ DF_1_DIRECT,		MSG_DF_1_DIRECT_CFNP },
    289 		{ DF_1_TRANS,		MSG_DF_1_TRANS_CFNP },
    290 		{ DF_1_INTERPOSE,	MSG_DF_1_INTERPOSE_CFNP },
    291 		{ DF_1_NODEFLIB,	MSG_DF_1_NODEFLIB_CFNP },
    292 		{ DF_1_NODUMP,		MSG_DF_1_NODUMP_CFNP },
    293 		{ DF_1_CONFALT,		MSG_DF_1_CONFALT_CFNP },
    294 		{ DF_1_ENDFILTEE,	MSG_DF_1_ENDFILTEE_CFNP },
    295 		{ DF_1_DISPRELDNE,	MSG_DF_1_DISPRELDNE_CFNP },
    296 		{ DF_1_DISPRELPND,	MSG_DF_1_DISPRELPND_CFNP },
    297 		{ DF_1_NODIRECT,	MSG_DF_1_NODIRECT_CFNP },
    298 		{ DF_1_IGNMULDEF,	MSG_DF_1_IGNMULDEF_CFNP },
    299 		{ DF_1_NOKSYMS,		MSG_DF_1_NOKSYMS_CFNP },
    300 		{ DF_1_NOHDR,		MSG_DF_1_NOHDR_CFNP },
    301 		{ DF_1_EDITED,		MSG_DF_1_EDITED_CFNP },
    302 		{ DF_1_NORELOC,		MSG_DF_1_NORELOC_CFNP },
    303 		{ DF_1_SYMINTPOSE,	MSG_DF_1_SYMINTPOSE_CFNP },
    304 		{ DF_1_GLOBAUDIT,	MSG_DF_1_GLOBAUDIT_CFNP },
    305 		{ DF_1_SINGLETON,	MSG_DF_1_SINGLETON_CFNP },
    306 		{ 0,			0 }
    307 	};
    308 	static const Val_desc vda_nf[] = {
    309 		{ DF_1_NOW,		MSG_DF_1_NOW_NF },
    310 		{ DF_1_GLOBAL,		MSG_DF_1_GLOBAL_NF },
    311 		{ DF_1_GROUP,		MSG_DF_1_GROUP_NF },
    312 		{ DF_1_NODELETE,	MSG_DF_1_NODELETE_NF },
    313 		{ DF_1_LOADFLTR,	MSG_DF_1_LOADFLTR_NF },
    314 		{ DF_1_INITFIRST,	MSG_DF_1_INITFIRST_NF },
    315 		{ DF_1_NOOPEN,		MSG_DF_1_NOOPEN_NF },
    316 		{ DF_1_ORIGIN,		MSG_DF_1_ORIGIN_NF },
    317 		{ DF_1_DIRECT,		MSG_DF_1_DIRECT_NF },
    318 		{ DF_1_TRANS,		MSG_DF_1_TRANS_NF },
    319 		{ DF_1_INTERPOSE,	MSG_DF_1_INTERPOSE_NF },
    320 		{ DF_1_NODEFLIB,	MSG_DF_1_NODEFLIB_NF },
    321 		{ DF_1_NODUMP,		MSG_DF_1_NODUMP_NF },
    322 		{ DF_1_CONFALT,		MSG_DF_1_CONFALT_NF },
    323 		{ DF_1_ENDFILTEE,	MSG_DF_1_ENDFILTEE_NF },
    324 		{ DF_1_DISPRELDNE,	MSG_DF_1_DISPRELDNE_NF },
    325 		{ DF_1_DISPRELPND,	MSG_DF_1_DISPRELPND_NF },
    326 		{ DF_1_NODIRECT,	MSG_DF_1_NODIRECT_NF },
    327 		{ DF_1_IGNMULDEF,	MSG_DF_1_IGNMULDEF_NF },
    328 		{ DF_1_NOKSYMS,		MSG_DF_1_NOKSYMS_NF },
    329 		{ DF_1_NOHDR,		MSG_DF_1_NOHDR_NF },
    330 		{ DF_1_EDITED,		MSG_DF_1_EDITED_NF },
    331 		{ DF_1_NORELOC,		MSG_DF_1_NORELOC_NF },
    332 		{ DF_1_SYMINTPOSE,	MSG_DF_1_SYMINTPOSE_NF },
    333 		{ DF_1_GLOBAUDIT,	MSG_DF_1_GLOBAUDIT_NF },
    334 		{ DF_1_SINGLETON,	MSG_DF_1_SINGLETON_NF },
    335 		{ 0,			0 }
    336 	};
    337 
    338 	switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
    339 	case CONV_FMT_ALT_CF:
    340 		return (vda_cf);
    341 	case CONV_FMT_ALT_CFNP:
    342 		return (vda_cfnp);
    343 	case CONV_FMT_ALT_NF:
    344 		return (vda_nf);
    345 	}
    346 
    347 	return (vda_def);
    348 }
    349 
    350 conv_iter_ret_t
    351 conv_iter_dyn_flag1(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func,
    352     void *uvalue)
    353 {
    354 	return (conv_iter_vd(conv_dyn_flag1_strings(fmt_flags), func, uvalue));
    355 }
    356 
    357 const Val_desc *
    358 conv_dyn_feature1_strings(Conv_fmt_flags_t fmt_flags)
    359 {
    360 #define	FEATSZ	CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
    361 	MSG_DTF_1_PARINIT_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    362 	MSG_DTF_1_CONFEXP_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    363 	CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
    364 
    365 	/*
    366 	 * Ensure that Conv_dyn_feature1_buf_t is large enough:
    367 	 *
    368 	 * FEATSZ is the real min size of the buffer required by
    369 	 * conv_dyn_feature1(). However, Conv_dyn_feature1_buf_t uses
    370 	 * CONV_DYN_FEATURE1_BUFSIZE to set the buffer size. We do things
    371 	 * this way because the definition of FEATSZ uses information that
    372 	 * is not available in the environment of other programs that include
    373 	 * the conv.h header file.
    374 	 */
    375 #if (CONV_DYN_FEATURE1_BUFSIZE != FEATSZ) && !defined(__lint)
    376 #define	REPORT_BUFSIZE FEATSZ
    377 #include "report_bufsize.h"
    378 #error "CONV_DYN_FEATURE1_BUFSIZE does not match FEATSZ"
    379 #endif
    380 
    381 	static const Val_desc vda_cf[] = {
    382 		{ DTF_1_PARINIT,	MSG_DTF_1_PARINIT_CF },
    383 		{ DTF_1_CONFEXP,	MSG_DTF_1_CONFEXP_CF },
    384 		{ 0,			0 }
    385 	};
    386 	static const Val_desc vda_cfnp[] = {
    387 		{ DTF_1_PARINIT,	MSG_DTF_1_PARINIT_CFNP },
    388 		{ DTF_1_CONFEXP,	MSG_DTF_1_CONFEXP_CFNP },
    389 		{ 0,			0 }
    390 	};
    391 	static const Val_desc vda_nf[] = {
    392 		{ DTF_1_PARINIT,	MSG_DTF_1_PARINIT_NF },
    393 		{ DTF_1_CONFEXP,	MSG_DTF_1_CONFEXP_NF },
    394 		{ 0,			0 }
    395 	};
    396 
    397 	switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
    398 	case CONV_FMT_ALT_CF:
    399 		return (vda_cf);
    400 	case CONV_FMT_ALT_NF:
    401 		return (vda_nf);
    402 	}
    403 
    404 	return (vda_cfnp);
    405 }
    406 
    407 conv_iter_ret_t
    408 conv_iter_dyn_feature1(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func,
    409     void *uvalue)
    410 {
    411 	return (conv_iter_vd(conv_dyn_feature1_strings(fmt_flags),
    412 	    func, uvalue));
    413 }
    414 
    415 const conv_ds_t **
    416 conv_dyn_tag_strings(conv_iter_osabi_t osabi, Half mach,
    417     Conv_fmt_flags_t fmt_flags)
    418 {
    419 	/*
    420 	 * Maximum # of items that can be in the returned array. Size this
    421 	 * by counting the maximum depth in the switch statement that fills
    422 	 * retarr at the end of this function.
    423 	 */
    424 #define	MAX_RET	12
    425 
    426 	/*
    427 	 * Generic dynamic tags:
    428 	 * -	Note hole between DT_FLAGS and DT_PREINIT_ARRAY (tag 32).
    429 	 *	We use a 0, which is the signal for "not defined".
    430 	 * -	This range has alternative names for dump, requiring an
    431 	 *	additional array.
    432 	 */
    433 	static const Msg	tags_null_cf[] = {
    434 		MSG_DT_NULL_CF,			MSG_DT_NEEDED_CF,
    435 		MSG_DT_PLTRELSZ_CF,		MSG_DT_PLTGOT_CF,
    436 		MSG_DT_HASH_CF,			MSG_DT_STRTAB_CF,
    437 		MSG_DT_SYMTAB_CF,		MSG_DT_RELA_CF,
    438 		MSG_DT_RELASZ_CF,		MSG_DT_RELAENT_CF,
    439 		MSG_DT_STRSZ_CF,		MSG_DT_SYMENT_CF,
    440 		MSG_DT_INIT_CF,			MSG_DT_FINI_CF,
    441 		MSG_DT_SONAME_CF,		MSG_DT_RPATH_CF,
    442 		MSG_DT_SYMBOLIC_CF,		MSG_DT_REL_CF,
    443 		MSG_DT_RELSZ_CF,		MSG_DT_RELENT_CF,
    444 		MSG_DT_PLTREL_CF,		MSG_DT_DEBUG_CF,
    445 		MSG_DT_TEXTREL_CF,		MSG_DT_JMPREL_CF,
    446 		MSG_DT_BIND_NOW_CF,		MSG_DT_INIT_ARRAY_CF,
    447 		MSG_DT_FINI_ARRAY_CF,		MSG_DT_INIT_ARRAYSZ_CF,
    448 		MSG_DT_FINI_ARRAYSZ_CF,		MSG_DT_RUNPATH_CF,
    449 		MSG_DT_FLAGS_CF,		0,
    450 		MSG_DT_PREINIT_ARRAY_CF,	MSG_DT_PREINIT_ARRAYSZ_CF
    451 	};
    452 	static const Msg	tags_null_cfnp[] = {
    453 		MSG_DT_NULL_CFNP,		MSG_DT_NEEDED_CFNP,
    454 		MSG_DT_PLTRELSZ_CFNP,		MSG_DT_PLTGOT_CFNP,
    455 		MSG_DT_HASH_CFNP,		MSG_DT_STRTAB_CFNP,
    456 		MSG_DT_SYMTAB_CFNP,		MSG_DT_RELA_CFNP,
    457 		MSG_DT_RELASZ_CFNP,		MSG_DT_RELAENT_CFNP,
    458 		MSG_DT_STRSZ_CFNP,		MSG_DT_SYMENT_CFNP,
    459 		MSG_DT_INIT_CFNP,		MSG_DT_FINI_CFNP,
    460 		MSG_DT_SONAME_CFNP,		MSG_DT_RPATH_CFNP,
    461 		MSG_DT_SYMBOLIC_CFNP,		MSG_DT_REL_CFNP,
    462 		MSG_DT_RELSZ_CFNP,		MSG_DT_RELENT_CFNP,
    463 		MSG_DT_PLTREL_CFNP,		MSG_DT_DEBUG_CFNP,
    464 		MSG_DT_TEXTREL_CFNP,		MSG_DT_JMPREL_CFNP,
    465 		MSG_DT_BIND_NOW_CFNP,		MSG_DT_INIT_ARRAY_CFNP,
    466 		MSG_DT_FINI_ARRAY_CFNP,		MSG_DT_INIT_ARRAYSZ_CFNP,
    467 		MSG_DT_FINI_ARRAYSZ_CFNP,	MSG_DT_RUNPATH_CFNP,
    468 		MSG_DT_FLAGS_CFNP,		0,
    469 		MSG_DT_PREINIT_ARRAY_CFNP,	MSG_DT_PREINIT_ARRAYSZ_CFNP
    470 	};
    471 	static const Msg	tags_null_nf[] = {
    472 		MSG_DT_NULL_NF,			MSG_DT_NEEDED_NF,
    473 		MSG_DT_PLTRELSZ_NF,		MSG_DT_PLTGOT_NF,
    474 		MSG_DT_HASH_NF,			MSG_DT_STRTAB_NF,
    475 		MSG_DT_SYMTAB_NF,		MSG_DT_RELA_NF,
    476 		MSG_DT_RELASZ_NF,		MSG_DT_RELAENT_NF,
    477 		MSG_DT_STRSZ_NF,		MSG_DT_SYMENT_NF,
    478 		MSG_DT_INIT_NF,			MSG_DT_FINI_NF,
    479 		MSG_DT_SONAME_NF,		MSG_DT_RPATH_NF,
    480 		MSG_DT_SYMBOLIC_NF,		MSG_DT_REL_NF,
    481 		MSG_DT_RELSZ_NF,		MSG_DT_RELENT_NF,
    482 		MSG_DT_PLTREL_NF,		MSG_DT_DEBUG_NF,
    483 		MSG_DT_TEXTREL_NF,		MSG_DT_JMPREL_NF,
    484 		MSG_DT_BIND_NOW_NF,		MSG_DT_INIT_ARRAY_NF,
    485 		MSG_DT_FINI_ARRAY_NF,		MSG_DT_INIT_ARRAYSZ_NF,
    486 		MSG_DT_FINI_ARRAYSZ_NF,		MSG_DT_RUNPATH_NF,
    487 		MSG_DT_FLAGS_NF,		0,
    488 		MSG_DT_PREINIT_ARRAY_NF,	MSG_DT_PREINIT_ARRAYSZ_NF
    489 	};
    490 	static const Msg	tags_null_dmp[] = {
    491 		MSG_DT_NULL_CFNP,		MSG_DT_NEEDED_CFNP,
    492 		MSG_DT_PLTRELSZ_DMP,		MSG_DT_PLTGOT_CFNP,
    493 		MSG_DT_HASH_CFNP,		MSG_DT_STRTAB_CFNP,
    494 		MSG_DT_SYMTAB_CFNP,		MSG_DT_RELA_CFNP,
    495 		MSG_DT_RELASZ_CFNP,		MSG_DT_RELAENT_CFNP,
    496 		MSG_DT_STRSZ_CFNP,		MSG_DT_SYMENT_CFNP,
    497 		MSG_DT_INIT_CFNP,		MSG_DT_FINI_CFNP,
    498 		MSG_DT_SONAME_CFNP,		MSG_DT_RPATH_CFNP,
    499 		MSG_DT_SYMBOLIC_DMP,		MSG_DT_REL_CFNP,
    500 		MSG_DT_RELSZ_CFNP,		MSG_DT_RELENT_CFNP,
    501 		MSG_DT_PLTREL_CFNP,		MSG_DT_DEBUG_CFNP,
    502 		MSG_DT_TEXTREL_CFNP,		MSG_DT_JMPREL_CFNP,
    503 		MSG_DT_BIND_NOW_CFNP,		MSG_DT_INIT_ARRAY_CFNP,
    504 		MSG_DT_FINI_ARRAY_CFNP,		MSG_DT_INIT_ARRAYSZ_CFNP,
    505 		MSG_DT_FINI_ARRAYSZ_CFNP,	MSG_DT_RUNPATH_CFNP,
    506 		MSG_DT_FLAGS_CFNP,		0,
    507 		MSG_DT_PREINIT_ARRAY_CFNP,	MSG_DT_PREINIT_ARRAYSZ_CFNP
    508 	};
    509 	static const conv_ds_msg_t ds_null_cf = {
    510 	    CONV_DS_MSG_INIT(DT_NULL, tags_null_cf) };
    511 	static const conv_ds_msg_t ds_null_cfnp = {
    512 	    CONV_DS_MSG_INIT(DT_NULL, tags_null_cfnp) };
    513 	static const conv_ds_msg_t ds_null_nf = {
    514 	    CONV_DS_MSG_INIT(DT_NULL, tags_null_nf) };
    515 	static const conv_ds_msg_t ds_null_dmp = {
    516 	    CONV_DS_MSG_INIT(DT_NULL, tags_null_dmp) };
    517 
    518 	/*
    519 	 * DT_SPARC_REGISTER was originally assigned 0x7000001. It is processor
    520 	 * specific, and should have been in the range DT_LOPROC-DT_HIPROC
    521 	 * instead of here. When the error was fixed,
    522 	 * DT_DEPRECATED_SPARC_REGISTER was created to maintain backward
    523 	 * compatability.
    524 	 */
    525 	static const Msg	tags_sdreg_cf[] = {
    526 	    MSG_DT_DEP_SPARC_REG_CF };
    527 	static const Msg	tags_sdreg_cfnp[] = {
    528 	    MSG_DT_DEP_SPARC_REG_CFNP };
    529 	static const Msg	tags_sdreg_nf[] = {
    530 	    MSG_DT_DEP_SPARC_REG_NF };
    531 
    532 	static const conv_ds_msg_t ds_sdreg_cf = {
    533 	    CONV_DS_MSG_INIT(DT_DEPRECATED_SPARC_REGISTER, tags_sdreg_cf) };
    534 	static const conv_ds_msg_t ds_sdreg_cfnp = {
    535 	    CONV_DS_MSG_INIT(DT_DEPRECATED_SPARC_REGISTER, tags_sdreg_cfnp) };
    536 	static const conv_ds_msg_t ds_sdreg_nf = {
    537 	    CONV_DS_MSG_INIT(DT_DEPRECATED_SPARC_REGISTER, tags_sdreg_nf) };
    538 
    539 
    540 	/*
    541 	 * SUNW: DT_LOOS -> DT_HIOS range. Note holes between DT_SUNW_TLSSORTSZ,
    542 	 * DT_SUNW_STRPAD, and DT_SUNW_LDMACH. We handle the outliers
    543 	 * separately below as single values.
    544 	 */
    545 	static const Msg	tags_sunw_auxiliary_cf[] = {
    546 		MSG_DT_SUNW_AUXILIARY_CF,	MSG_DT_SUNW_RTLDINF_CF,
    547 		MSG_DT_SUNW_FILTER_CF,		MSG_DT_SUNW_CAP_CF,
    548 		MSG_DT_SUNW_SYMTAB_CF,		MSG_DT_SUNW_SYMSZ_CF,
    549 		MSG_DT_SUNW_SORTENT_CF,		MSG_DT_SUNW_SYMSORT_CF,
    550 		MSG_DT_SUNW_SYMSORTSZ_CF,	MSG_DT_SUNW_TLSSORT_CF,
    551 		MSG_DT_SUNW_TLSSORTSZ_CF,	0,
    552 		MSG_DT_SUNW_STRPAD_CF,		0,
    553 		MSG_DT_SUNW_LDMACH_CF
    554 	};
    555 	static const Msg	tags_sunw_auxiliary_cfnp[] = {
    556 		MSG_DT_SUNW_AUXILIARY_CFNP,	MSG_DT_SUNW_RTLDINF_CFNP,
    557 		MSG_DT_SUNW_FILTER_CFNP,	MSG_DT_SUNW_CAP_CFNP,
    558 		MSG_DT_SUNW_SYMTAB_CFNP,	MSG_DT_SUNW_SYMSZ_CFNP,
    559 		MSG_DT_SUNW_SORTENT_CFNP,	MSG_DT_SUNW_SYMSORT_CFNP,
    560 		MSG_DT_SUNW_SYMSORTSZ_CFNP,	MSG_DT_SUNW_TLSSORT_CFNP,
    561 		MSG_DT_SUNW_TLSSORTSZ_CFNP,	0,
    562 		MSG_DT_SUNW_STRPAD_CFNP,	0,
    563 		MSG_DT_SUNW_LDMACH_CFNP
    564 	};
    565 	static const Msg	tags_sunw_auxiliary_nf[] = {
    566 		MSG_DT_SUNW_AUXILIARY_NF,	MSG_DT_SUNW_RTLDINF_NF,
    567 		MSG_DT_SUNW_FILTER_NF,		MSG_DT_SUNW_CAP_NF,
    568 		MSG_DT_SUNW_SYMTAB_NF,		MSG_DT_SUNW_SYMSZ_NF,
    569 		MSG_DT_SUNW_SORTENT_NF,		MSG_DT_SUNW_SYMSORT_NF,
    570 		MSG_DT_SUNW_SYMSORTSZ_NF,	MSG_DT_SUNW_TLSSORT_NF,
    571 		MSG_DT_SUNW_TLSSORTSZ_NF,	0,
    572 		MSG_DT_SUNW_STRPAD_NF,		0,
    573 		MSG_DT_SUNW_LDMACH_NF
    574 	};
    575 	static const conv_ds_msg_t ds_sunw_auxiliary_cf = {
    576 	    CONV_DS_MSG_INIT(DT_SUNW_AUXILIARY, tags_sunw_auxiliary_cf) };
    577 	static const conv_ds_msg_t ds_sunw_auxiliary_cfnp = {
    578 	    CONV_DS_MSG_INIT(DT_SUNW_AUXILIARY, tags_sunw_auxiliary_cfnp) };
    579 	static const conv_ds_msg_t ds_sunw_auxiliary_nf = {
    580 	    CONV_DS_MSG_INIT(DT_SUNW_AUXILIARY, tags_sunw_auxiliary_nf) };
    581 
    582 	/*
    583 	 * GNU: (In DT_VALRNGLO section) DT_GNU_PRELINKED - DT_GNU_LIBLISTSZ
    584 	 */
    585 	static const Msg	tags_gnu_prelinked_cf[] = {
    586 		MSG_DT_GNU_PRELINKED_CF,	MSG_DT_GNU_CONFLICTSZ_CF,
    587 		MSG_DT_GNU_LIBLISTSZ_CF
    588 	};
    589 	static const Msg	tags_gnu_prelinked_cfnp[] = {
    590 		MSG_DT_GNU_PRELINKED_CFNP,	MSG_DT_GNU_CONFLICTSZ_CFNP,
    591 		MSG_DT_GNU_LIBLISTSZ_CFNP
    592 	};
    593 	static const Msg	tags_gnu_prelinked_nf[] = {
    594 		MSG_DT_GNU_PRELINKED_NF,	MSG_DT_GNU_CONFLICTSZ_NF,
    595 		MSG_DT_GNU_LIBLISTSZ_NF
    596 	};
    597 	static const conv_ds_msg_t ds_gnu_prelinked_cf = {
    598 	    CONV_DS_MSG_INIT(DT_GNU_PRELINKED, tags_gnu_prelinked_cf) };
    599 	static const conv_ds_msg_t ds_gnu_prelinked_cfnp = {
    600 	    CONV_DS_MSG_INIT(DT_GNU_PRELINKED, tags_gnu_prelinked_cfnp) };
    601 	static const conv_ds_msg_t ds_gnu_prelinked_nf = {
    602 	    CONV_DS_MSG_INIT(DT_GNU_PRELINKED, tags_gnu_prelinked_nf) };
    603 
    604 	/*
    605 	 * SUNW: DT_VALRNGLO - DT_VALRNGHI range.
    606 	 */
    607 	static const Msg	tags_checksum_cf[] = {
    608 		MSG_DT_CHECKSUM_CF,		MSG_DT_PLTPADSZ_CF,
    609 		MSG_DT_MOVEENT_CF,		MSG_DT_MOVESZ_CF,
    610 		MSG_DT_FEATURE_1_CF,		MSG_DT_POSFLAG_1_CF,
    611 		MSG_DT_SYMINSZ_CF,		MSG_DT_SYMINENT_CF
    612 	};
    613 	static const Msg	tags_checksum_cfnp[] = {
    614 		MSG_DT_CHECKSUM_CFNP,		MSG_DT_PLTPADSZ_CFNP,
    615 		MSG_DT_MOVEENT_CFNP,		MSG_DT_MOVESZ_CFNP,
    616 		MSG_DT_FEATURE_1_CFNP,		MSG_DT_POSFLAG_1_CFNP,
    617 		MSG_DT_SYMINSZ_CFNP,		MSG_DT_SYMINENT_CFNP
    618 	};
    619 	static const Msg	tags_checksum_nf[] = {
    620 		MSG_DT_CHECKSUM_NF,		MSG_DT_PLTPADSZ_NF,
    621 		MSG_DT_MOVEENT_NF,		MSG_DT_MOVESZ_NF,
    622 		MSG_DT_FEATURE_1_NF,		MSG_DT_POSFLAG_1_NF,
    623 		MSG_DT_SYMINSZ_NF,		MSG_DT_SYMINENT_NF
    624 	};
    625 	static const conv_ds_msg_t ds_checksum_cf = {
    626 	    CONV_DS_MSG_INIT(DT_CHECKSUM, tags_checksum_cf) };
    627 	static const conv_ds_msg_t ds_checksum_cfnp = {
    628 	    CONV_DS_MSG_INIT(DT_CHECKSUM, tags_checksum_cfnp) };
    629 	static const conv_ds_msg_t ds_checksum_nf = {
    630 	    CONV_DS_MSG_INIT(DT_CHECKSUM, tags_checksum_nf) };
    631 
    632 	/*
    633 	 * GNU: (In DT_ADDRRNGLO section) DT_GNU_HASH - DT_GNU_LIBLIST
    634 	 */
    635 	static const Msg	tags_gnu_hash_cf[] = {
    636 		MSG_DT_GNU_HASH_CF,		MSG_DT_TLSDESC_PLT_CF,
    637 		MSG_DT_TLSDESC_GOT_CF,		MSG_DT_GNU_CONFLICT_CF,
    638 		MSG_DT_GNU_LIBLIST_CF
    639 	};
    640 	static const Msg	tags_gnu_hash_cfnp[] = {
    641 		MSG_DT_GNU_HASH_CFNP,		MSG_DT_TLSDESC_PLT_CFNP,
    642 		MSG_DT_TLSDESC_GOT_CFNP,	MSG_DT_GNU_CONFLICT_CFNP,
    643 		MSG_DT_GNU_LIBLIST_CFNP
    644 	};
    645 	static const Msg	tags_gnu_hash_nf[] = {
    646 		MSG_DT_GNU_HASH_NF,		MSG_DT_TLSDESC_PLT_NF,
    647 		MSG_DT_TLSDESC_GOT_NF,		MSG_DT_GNU_CONFLICT_NF,
    648 		MSG_DT_GNU_LIBLIST_NF
    649 	};
    650 	static const conv_ds_msg_t ds_gnu_hash_cf = {
    651 	    CONV_DS_MSG_INIT(DT_GNU_HASH, tags_gnu_hash_cf) };
    652 	static const conv_ds_msg_t ds_gnu_hash_cfnp = {
    653 	    CONV_DS_MSG_INIT(DT_GNU_HASH, tags_gnu_hash_cfnp) };
    654 	static const conv_ds_msg_t ds_gnu_hash_nf = {
    655 	    CONV_DS_MSG_INIT(DT_GNU_HASH, tags_gnu_hash_nf) };
    656 
    657 	/*
    658 	 * SUNW: DT_ADDRRNGLO - DT_ADDRRNGHI range.
    659 	 */
    660 	static const Msg	tags_config_cf[] = {
    661 		MSG_DT_CONFIG_CF,		MSG_DT_DEPAUDIT_CF,
    662 		MSG_DT_AUDIT_CF,		MSG_DT_PLTPAD_CF,
    663 		MSG_DT_MOVETAB_CF,		MSG_DT_SYMINFO_CF
    664 	};
    665 	static const Msg	tags_config_cfnp[] = {
    666 		MSG_DT_CONFIG_CFNP,		MSG_DT_DEPAUDIT_CFNP,
    667 		MSG_DT_AUDIT_CFNP,		MSG_DT_PLTPAD_CFNP,
    668 		MSG_DT_MOVETAB_CFNP,		MSG_DT_SYMINFO_CFNP
    669 	};
    670 	static const Msg	tags_config_nf[] = {
    671 		MSG_DT_CONFIG_NF,		MSG_DT_DEPAUDIT_NF,
    672 		MSG_DT_AUDIT_NF,		MSG_DT_PLTPAD_NF,
    673 		MSG_DT_MOVETAB_NF,		MSG_DT_SYMINFO_NF
    674 	};
    675 	static const conv_ds_msg_t ds_config_cf = {
    676 	    CONV_DS_MSG_INIT(DT_CONFIG, tags_config_cf) };
    677 	static const conv_ds_msg_t ds_config_cfnp = {
    678 	    CONV_DS_MSG_INIT(DT_CONFIG, tags_config_cfnp) };
    679 	static const conv_ds_msg_t ds_config_nf = {
    680 	    CONV_DS_MSG_INIT(DT_CONFIG, tags_config_nf) };
    681 
    682 	/*
    683 	 * SUNW: generic range. Note hole between DT_VERSYM and DT_RELACOUNT.
    684 	 */
    685 	static const Msg	tags_versym_cf[] = { MSG_DT_VERSYM_CF };
    686 	static const Msg	tags_versym_cfnp[] = { MSG_DT_VERSYM_CFNP };
    687 	static const Msg	tags_versym_nf[] = { MSG_DT_VERSYM_NF };
    688 	static const conv_ds_msg_t ds_versym_cf = {
    689 	    CONV_DS_MSG_INIT(DT_VERSYM, tags_versym_cf) };
    690 	static const conv_ds_msg_t ds_versym_cfnp = {
    691 	    CONV_DS_MSG_INIT(DT_VERSYM, tags_versym_cfnp) };
    692 	static const conv_ds_msg_t ds_versym_nf = {
    693 	    CONV_DS_MSG_INIT(DT_VERSYM, tags_versym_nf) };
    694 
    695 	static const Msg	tags_relacount_cf[] = {
    696 		MSG_DT_RELACOUNT_CF,		MSG_DT_RELCOUNT_CF,
    697 		MSG_DT_FLAGS_1_CF,		MSG_DT_VERDEF_CF,
    698 		MSG_DT_VERDEFNUM_CF,		MSG_DT_VERNEED_CF,
    699 		MSG_DT_VERNEEDNUM_CF
    700 	};
    701 	static const Msg	tags_relacount_cfnp[] = {
    702 		MSG_DT_RELACOUNT_CFNP,		MSG_DT_RELCOUNT_CFNP,
    703 		MSG_DT_FLAGS_1_CFNP,		MSG_DT_VERDEF_CFNP,
    704 		MSG_DT_VERDEFNUM_CFNP,		MSG_DT_VERNEED_CFNP,
    705 		MSG_DT_VERNEEDNUM_CFNP
    706 	};
    707 	static const Msg	tags_relacount_nf[] = {
    708 		MSG_DT_RELACOUNT_NF,		MSG_DT_RELCOUNT_NF,
    709 		MSG_DT_FLAGS_1_NF,		MSG_DT_VERDEF_NF,
    710 		MSG_DT_VERDEFNUM_NF,		MSG_DT_VERNEED_NF,
    711 		MSG_DT_VERNEEDNUM_NF
    712 	};
    713 	static const conv_ds_msg_t ds_relacount_cf = {
    714 	    CONV_DS_MSG_INIT(DT_RELACOUNT, tags_relacount_cf) };
    715 	static const conv_ds_msg_t ds_relacount_cfnp = {
    716 	    CONV_DS_MSG_INIT(DT_RELACOUNT, tags_relacount_cfnp) };
    717 	static const conv_ds_msg_t ds_relacount_nf = {
    718 	    CONV_DS_MSG_INIT(DT_RELACOUNT, tags_relacount_nf) };
    719 
    720 	/*
    721 	 * DT_LOPROC - DT_HIPROC range: solaris/sparc-only
    722 	 */
    723 	static const Msg tags_sparc_reg_cf[] = { MSG_DT_SPARC_REGISTER_CF };
    724 	static const Msg tags_sparc_reg_cfnp[] = { MSG_DT_SPARC_REGISTER_CFNP };
    725 	static const Msg tags_sparc_reg_nf[] = { MSG_DT_SPARC_REGISTER_NF };
    726 	static const Msg tags_sparc_reg_dmp[] = { MSG_DT_SPARC_REGISTER_DMP };
    727 	static const conv_ds_msg_t ds_sparc_reg_cf = {
    728 	    CONV_DS_MSG_INIT(DT_SPARC_REGISTER, tags_sparc_reg_cf) };
    729 	static const conv_ds_msg_t ds_sparc_reg_cfnp = {
    730 	    CONV_DS_MSG_INIT(DT_SPARC_REGISTER, tags_sparc_reg_cfnp) };
    731 	static const conv_ds_msg_t ds_sparc_reg_nf = {
    732 	    CONV_DS_MSG_INIT(DT_SPARC_REGISTER, tags_sparc_reg_nf) };
    733 	static const conv_ds_msg_t ds_sparc_reg_dmp = {
    734 	    CONV_DS_MSG_INIT(DT_SPARC_REGISTER, tags_sparc_reg_dmp) };
    735 
    736 	/*
    737 	 * DT_LOPROC - DT_HIPROC range: Solaris osabi, all hardware
    738 	 */
    739 	static const Msg	tags_auxiliary_cf[] = {
    740 		MSG_DT_AUXILIARY_CF,	MSG_DT_USED_CF,
    741 		MSG_DT_FILTER_CF
    742 	};
    743 	static const Msg	tags_auxiliary_cfnp[] = {
    744 		MSG_DT_AUXILIARY_CFNP,	MSG_DT_USED_CFNP,
    745 		MSG_DT_FILTER_CFNP
    746 	};
    747 	static const Msg	tags_auxiliary_nf[] = {
    748 		MSG_DT_AUXILIARY_NF,	MSG_DT_USED_NF,
    749 		MSG_DT_FILTER_NF
    750 	};
    751 	static const conv_ds_msg_t ds_auxiliary_cf = {
    752 	    CONV_DS_MSG_INIT(DT_AUXILIARY, tags_auxiliary_cf) };
    753 	static const conv_ds_msg_t ds_auxiliary_cfnp = {
    754 	    CONV_DS_MSG_INIT(DT_AUXILIARY, tags_auxiliary_cfnp) };
    755 	static const conv_ds_msg_t ds_auxiliary_nf = {
    756 	    CONV_DS_MSG_INIT(DT_AUXILIARY, tags_auxiliary_nf) };
    757 
    758 
    759 	static const conv_ds_t	*retarr[MAX_RET];
    760 
    761 	int	ndx = 0;
    762 	int	fmt_osabi = CONV_TYPE_FMT_ALT(fmt_flags);
    763 	int	mach_sparc, osabi_solaris, osabi_linux;
    764 
    765 
    766 
    767 	osabi_solaris = (osabi == ELFOSABI_NONE) ||
    768 	    (osabi == ELFOSABI_SOLARIS) || (osabi == CONV_OSABI_ALL);
    769 	osabi_linux = (osabi == ELFOSABI_LINUX) || (osabi == CONV_OSABI_ALL);
    770 	mach_sparc = (mach == EM_SPARC) || (mach == EM_SPARCV9) ||
    771 	    (mach == EM_SPARC32PLUS) || (mach == CONV_MACH_ALL);
    772 
    773 	/*
    774 	 * Fill in retarr with the descriptors for the messages that
    775 	 * apply to the current osabi. Note that we order these items such
    776 	 * that the more common are placed at the beginning, and the less
    777 	 * likely at the end. This should speed the common case.
    778 	 *
    779 	 * Note that the CFNP and DMP styles are very similar, so they
    780 	 * are combined in 'default', and fmt_osabi is consulted when there
    781 	 * are differences.
    782 	 */
    783 	switch (fmt_osabi) {
    784 	case CONV_FMT_ALT_CF:
    785 		retarr[ndx++] = CONV_DS_ADDR(ds_null_cf);
    786 		if (osabi_solaris)
    787 			retarr[ndx++] = CONV_DS_ADDR(ds_sunw_auxiliary_cf);
    788 		retarr[ndx++] = CONV_DS_ADDR(ds_checksum_cf);
    789 		retarr[ndx++] = CONV_DS_ADDR(ds_config_cf);
    790 		retarr[ndx++] = CONV_DS_ADDR(ds_versym_cf);
    791 		retarr[ndx++] = CONV_DS_ADDR(ds_relacount_cf);
    792 		if (osabi_solaris) {
    793 			retarr[ndx++] = CONV_DS_ADDR(ds_auxiliary_cf);
    794 			if (mach_sparc) {
    795 				retarr[ndx++] = CONV_DS_ADDR(ds_sparc_reg_cf);
    796 				retarr[ndx++] = CONV_DS_ADDR(ds_sdreg_cf);
    797 			}
    798 		}
    799 		if (osabi_linux) {
    800 			retarr[ndx++] = CONV_DS_ADDR(ds_gnu_prelinked_cf);
    801 			retarr[ndx++] = CONV_DS_ADDR(ds_gnu_hash_cf);
    802 		}
    803 		break;
    804 
    805 	case CONV_FMT_ALT_NF:
    806 		retarr[ndx++] = CONV_DS_ADDR(ds_null_nf);
    807 		if (osabi_solaris)
    808 			retarr[ndx++] = CONV_DS_ADDR(ds_sunw_auxiliary_nf);
    809 		retarr[ndx++] = CONV_DS_ADDR(ds_checksum_nf);
    810 		retarr[ndx++] = CONV_DS_ADDR(ds_config_nf);
    811 		retarr[ndx++] = CONV_DS_ADDR(ds_versym_nf);
    812 		retarr[ndx++] = CONV_DS_ADDR(ds_relacount_nf);
    813 		if (osabi_solaris) {
    814 			retarr[ndx++] = CONV_DS_ADDR(ds_auxiliary_nf);
    815 			if (mach_sparc) {
    816 				retarr[ndx++] = CONV_DS_ADDR(ds_sparc_reg_nf);
    817 				retarr[ndx++] = CONV_DS_ADDR(ds_sdreg_nf);
    818 			}
    819 		}
    820 		if (osabi_linux) {
    821 			retarr[ndx++] = CONV_DS_ADDR(ds_gnu_prelinked_nf);
    822 			retarr[ndx++] = CONV_DS_ADDR(ds_gnu_hash_nf);
    823 		}
    824 		break;
    825 	default:
    826 		/*
    827 		 * The default style for the generic range is CFNP,
    828 		 * while dump has a couple of different strings.
    829 		 */
    830 
    831 		retarr[ndx++] = (fmt_osabi == CONV_FMT_ALT_DUMP) ?
    832 		    CONV_DS_ADDR(ds_null_dmp) : CONV_DS_ADDR(ds_null_cfnp);
    833 		if (osabi_solaris)
    834 			retarr[ndx++] = CONV_DS_ADDR(ds_sunw_auxiliary_cfnp);
    835 		retarr[ndx++] = CONV_DS_ADDR(ds_checksum_cfnp);
    836 		retarr[ndx++] = CONV_DS_ADDR(ds_config_cfnp);
    837 		retarr[ndx++] = CONV_DS_ADDR(ds_versym_cfnp);
    838 		retarr[ndx++] = CONV_DS_ADDR(ds_relacount_cfnp);
    839 		if (osabi_solaris) {
    840 			retarr[ndx++] = CONV_DS_ADDR(ds_auxiliary_cfnp);
    841 			if (mach_sparc) {
    842 				/*
    843 				 * The default style for DT_SPARC_REGISTER
    844 				 * is the dump style, which omits the 'SPARC_'.
    845 				 * CFNP keeps the prefix.
    846 				 */
    847 				retarr[ndx++] =
    848 				    (fmt_osabi == CONV_FMT_ALT_CFNP) ?
    849 				    CONV_DS_ADDR(ds_sparc_reg_cfnp) :
    850 				    CONV_DS_ADDR(ds_sparc_reg_dmp);
    851 				retarr[ndx++] = CONV_DS_ADDR(ds_sdreg_cfnp);
    852 			}
    853 		}
    854 		if (osabi_linux) {
    855 			retarr[ndx++] = CONV_DS_ADDR(ds_gnu_prelinked_cfnp);
    856 			retarr[ndx++] = CONV_DS_ADDR(ds_gnu_hash_cfnp);
    857 		}
    858 		break;
    859 	}
    860 
    861 	retarr[ndx++] = NULL;
    862 	assert(ndx <= MAX_RET);
    863 	return (retarr);
    864 }
    865 
    866 conv_iter_ret_t
    867 conv_iter_dyn_tag(conv_iter_osabi_t osabi, Half mach,
    868     Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func, void *uvalue)
    869 {
    870 	return (conv_iter_ds(osabi, mach,
    871 	    conv_dyn_tag_strings(osabi, mach, fmt_flags), func, uvalue));
    872 }
    873 
    874 
    875 #define	BINDTSZ	CONV_EXPN_FIELD_DEF_PREFIX_SIZE +			\
    876 		MSG_BND_NEEDED_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    877 		MSG_BND_REFER_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    878 		MSG_BND_FILTER_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    879 		CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
    880 
    881 /*
    882  * Ensure that Conv_bnd_type_buf_t is large enough:
    883  *
    884  * BINDTSZ is the real minimum size of the buffer required by conv_bnd_type().
    885  * However, Conv_bnd_type_buf_t uses CONV_BND_TYPE_BUFSIZE to set the
    886  * buffer size. We do things this way because the definition of BINDTSZ uses
    887  * information that is not available in the environment of other programs
    888  * that include the conv.h header file.
    889  */
    890 #if (CONV_BND_TYPE_BUFSIZE != BINDTSZ) && !defined(__lint)
    891 #define	REPORT_BUFSIZE BINDTSZ
    892 #include "report_bufsize.h"
    893 #error "CONV_BND_TYPE_BUFSIZE does not match BINDTSZ"
    894 #endif
    895 
    896 const char *
    897 conv_bnd_type(uint_t flags, Conv_bnd_type_buf_t *bnd_type_buf)
    898 {
    899 	static const Val_desc vda[] = {
    900 		{ BND_NEEDED,		MSG_BND_NEEDED },
    901 		{ BND_REFER,		MSG_BND_REFER },
    902 		{ BND_FILTER,		MSG_BND_FILTER },
    903 		{ 0,			0 }
    904 	};
    905 	static CONV_EXPN_FIELD_ARG conv_arg = {
    906 	    NULL, sizeof (bnd_type_buf->buf) };
    907 
    908 	if (flags == 0)
    909 		return (MSG_ORIG(MSG_STR_EMPTY));
    910 
    911 	conv_arg.buf = bnd_type_buf->buf;
    912 	conv_arg.oflags = conv_arg.rflags = flags;
    913 	(void) conv_expn_field(&conv_arg, vda, 0);
    914 
    915 	return ((const char *)bnd_type_buf->buf);
    916 }
    917 
    918 /*
    919  * Note, conv_bnd_obj() is called with either:
    920  *	LML_FLG_OBJADDED (possibly with LML_FLG_OBJREEVAL added), or
    921  *	LML_FLG_OBJDELETED, or
    922  *	LML_FLG_ATEXIT.
    923  */
    924 #define	BINDOSZ	CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
    925 		MSG_BND_ADDED_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    926 		MSG_BND_REEVAL_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
    927 		CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
    928 
    929 /*
    930  * Ensure that Conv_bnd_obj_buf_t is large enough:
    931  *
    932  * BINDOSZ is the real minimum size of the buffer required by conv_bnd_obj().
    933  * However, Conv_bnd_obj_buf_t uses CONV_BND_OBJ_BUFSIZE to set the
    934  * buffer size. We do things this way because the definition of BINDOSZ uses
    935  * information that is not available in the environment of other programs
    936  * that include the conv.h header file.
    937  */
    938 #if (CONV_BND_OBJ_BUFSIZE != BINDOSZ) && !defined(__lint)
    939 #define	REPORT_BUFSIZE BINDOSZ
    940 #include "report_bufsize.h"
    941 #error "CONV_BND_OBJ_BUFSIZE does not match BINDOSZ"
    942 #endif
    943 
    944 const char *
    945 conv_bnd_obj(uint_t flags, Conv_bnd_obj_buf_t *bnd_obj_buf)
    946 {
    947 	static const Val_desc vda[] = {
    948 		{ LML_FLG_OBJADDED,	MSG_BND_ADDED },
    949 		{ LML_FLG_OBJREEVAL,	MSG_BND_REEVAL },
    950 		{ LML_FLG_OBJDELETED,	MSG_BND_DELETED },
    951 		{ LML_FLG_ATEXIT,	MSG_BND_ATEXIT },
    952 		{ 0,			0 }
    953 	};
    954 	static CONV_EXPN_FIELD_ARG conv_arg = {
    955 	    NULL, sizeof (bnd_obj_buf->buf) };
    956 
    957 	if ((flags & (LML_FLG_OBJADDED | LML_FLG_OBJREEVAL |
    958 	    LML_FLG_OBJDELETED | LML_FLG_ATEXIT)) == 0)
    959 		return (MSG_ORIG(MSG_BND_REVISIT));
    960 
    961 	/*
    962 	 * Note, we're not worried about unknown flags for this family, only
    963 	 * the selected flags are of interest, so we leave conv_arg.rflags
    964 	 * set to 0.
    965 	 */
    966 	conv_arg.buf = bnd_obj_buf->buf;
    967 	conv_arg.oflags = flags;
    968 	(void) conv_expn_field(&conv_arg, vda, 0);
    969 
    970 	return ((const char *)bnd_obj_buf->buf);
    971 }
    972