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 routines for ELF header attributes.
     29  */
     30 #include	<stdio.h>
     31 #include	<string.h>
     32 #include	"_conv.h"
     33 #include	"elf_msg.h"
     34 #include	<sys/elf_SPARC.h>
     35 
     36 
     37 
     38 static const conv_ds_t **
     39 ehdr_class_strings(Conv_fmt_flags_t fmt_flags)
     40 {
     41 	static const Msg	class_cf[] = {
     42 		MSG_ELFCLASSNONE_CF, MSG_ELFCLASS32_CF, MSG_ELFCLASS64_CF
     43 	};
     44 	static const Msg	class_nf[] = {
     45 		MSG_ELFCLASSNONE_NF, MSG_ELFCLASS32_NF, MSG_ELFCLASS64_NF
     46 	};
     47 	static const Msg	class_dump[] = {
     48 		MSG_ELFCLASSNONE_DMP, MSG_ELFCLASS32_DMP, MSG_ELFCLASS64_DMP
     49 	};
     50 
     51 	static const conv_ds_msg_t ds_classes_cf = {
     52 	    CONV_DS_MSG_INIT(ELFCLASSNONE, class_cf) };
     53 	static const conv_ds_msg_t ds_classes_nf = {
     54 	    CONV_DS_MSG_INIT(ELFCLASSNONE, class_nf) };
     55 	static const conv_ds_msg_t ds_classes_dump = {
     56 	    CONV_DS_MSG_INIT(ELFCLASSNONE, class_dump) };
     57 
     58 	static const conv_ds_t *ds_cf[] = { CONV_DS_ADDR(ds_classes_cf), NULL };
     59 	static const conv_ds_t *ds_nf[] = { CONV_DS_ADDR(ds_classes_nf), NULL };
     60 	static const conv_ds_t *ds_dump[] = {
     61 	    CONV_DS_ADDR(ds_classes_dump), NULL };
     62 
     63 	switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
     64 	case CONV_FMT_ALT_DUMP:
     65 	case CONV_FMT_ALT_FILE:
     66 		return (ds_dump);
     67 	case CONV_FMT_ALT_NF:
     68 		return (ds_nf);
     69 	}
     70 
     71 	return (ds_cf);
     72 }
     73 
     74 const char *
     75 conv_ehdr_class(uchar_t class, Conv_fmt_flags_t fmt_flags,
     76     Conv_inv_buf_t *inv_buf)
     77 {
     78 	return (conv_map_ds(ELFOSABI_NONE, EM_NONE, class,
     79 	    ehdr_class_strings(fmt_flags), fmt_flags, inv_buf));
     80 }
     81 
     82 conv_iter_ret_t
     83 conv_iter_ehdr_class(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func,
     84     void *uvalue)
     85 {
     86 	return (conv_iter_ds(ELFOSABI_NONE, EM_NONE,
     87 	    ehdr_class_strings(fmt_flags), func, uvalue));
     88 }
     89 
     90 static const conv_ds_t **
     91 ehdr_data_strings(Conv_fmt_flags_t fmt_flags)
     92 {
     93 	static const Msg	data_cf[] = {
     94 		MSG_ELFDATANONE_CF, MSG_ELFDATA2LSB_CF, MSG_ELFDATA2MSB_CF
     95 	};
     96 	static const Msg	data_nf[] = {
     97 		MSG_ELFDATANONE_NF, MSG_ELFDATA2LSB_NF, MSG_ELFDATA2MSB_NF
     98 	};
     99 	static const Msg	data_dump[] = {
    100 		MSG_ELFDATANONE_DMP, MSG_ELFDATA2LSB_DMP, MSG_ELFDATA2MSB_DMP
    101 	};
    102 	static const Msg	data_file[] = {
    103 		MSG_ELFDATANONE_DMP, MSG_ELFDATA2LSB_FIL, MSG_ELFDATA2MSB_FIL
    104 	};
    105 
    106 
    107 	static const conv_ds_msg_t ds_data_cf = {
    108 	    CONV_DS_MSG_INIT(ELFCLASSNONE, data_cf) };
    109 	static const conv_ds_msg_t ds_data_nf = {
    110 	    CONV_DS_MSG_INIT(ELFCLASSNONE, data_nf) };
    111 	static const conv_ds_msg_t ds_data_dump = {
    112 	    CONV_DS_MSG_INIT(ELFCLASSNONE, data_dump) };
    113 	static const conv_ds_msg_t ds_data_file = {
    114 	    CONV_DS_MSG_INIT(ELFCLASSNONE, data_file) };
    115 
    116 	static const conv_ds_t *ds_cf[] = { CONV_DS_ADDR(ds_data_cf), NULL };
    117 	static const conv_ds_t *ds_nf[] = { CONV_DS_ADDR(ds_data_nf), NULL };
    118 	static const conv_ds_t *ds_dump[] = { CONV_DS_ADDR(ds_data_dump),
    119 	    NULL };
    120 	static const conv_ds_t *ds_file[] = { CONV_DS_ADDR(ds_data_file),
    121 	    NULL };
    122 
    123 	switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
    124 	case CONV_FMT_ALT_DUMP:
    125 		return (ds_dump);
    126 	case CONV_FMT_ALT_FILE:
    127 		return (ds_file);
    128 	case CONV_FMT_ALT_NF:
    129 		return (ds_nf);
    130 	}
    131 
    132 	return (ds_cf);
    133 }
    134 
    135 const char *
    136 conv_ehdr_data(uchar_t data, Conv_fmt_flags_t fmt_flags,
    137     Conv_inv_buf_t *inv_buf)
    138 {
    139 	return (conv_map_ds(ELFOSABI_NONE, EM_NONE, data,
    140 	    ehdr_data_strings(fmt_flags), fmt_flags, inv_buf));
    141 }
    142 
    143 conv_iter_ret_t
    144 conv_iter_ehdr_data(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func,
    145     void *uvalue)
    146 {
    147 	return (conv_iter_ds(ELFOSABI_NONE, EM_NONE,
    148 	    ehdr_data_strings(fmt_flags), func, uvalue));
    149 }
    150 
    151 static const conv_ds_t **
    152 ehdr_mach_strings(Conv_fmt_flags_t fmt_flags)
    153 {
    154 
    155 	static const Msg mach_0_11_cf[] = {
    156 		MSG_EM_NONE_CF,		MSG_EM_M32_CF,
    157 		MSG_EM_SPARC_CF,	MSG_EM_386_CF,
    158 		MSG_EM_68K_CF,		MSG_EM_88K_CF,
    159 		MSG_EM_486_CF,		MSG_EM_860_CF,
    160 		MSG_EM_MIPS_CF,		MSG_EM_S370_CF,
    161 		MSG_EM_MIPS_RS3_LE_CF,	MSG_EM_RS6000_CF
    162 	};
    163 	static const Msg mach_0_11_nf[] = {
    164 		MSG_EM_NONE_NF,		MSG_EM_M32_NF,
    165 		MSG_EM_SPARC_NF,	MSG_EM_386_NF,
    166 		MSG_EM_68K_NF,		MSG_EM_88K_NF,
    167 		MSG_EM_486_NF,		MSG_EM_860_NF,
    168 		MSG_EM_MIPS_NF,		MSG_EM_S370_NF,
    169 		MSG_EM_MIPS_RS3_LE_NF,	MSG_EM_RS6000_NF
    170 	};
    171 	static const Msg mach_0_11_dmp[] = {
    172 		MSG_EM_NONE_DMP,	MSG_EM_M32_DMP,
    173 		MSG_EM_SPARC_DMP,	MSG_EM_386_DMP,
    174 		MSG_EM_68K_DMP,		MSG_EM_88K_DMP,
    175 		MSG_EM_486_DMP,		MSG_EM_860_DMP,
    176 		MSG_EM_MIPS_DMP,	MSG_EM_S370_CF,
    177 		MSG_EM_MIPS_RS3_LE_DMP,	MSG_EM_RS6000_DMP
    178 	};
    179 	static const conv_ds_msg_t ds_mach_0_11_cf = {
    180 	    CONV_DS_MSG_INIT(EM_NONE, mach_0_11_cf) };
    181 	static const conv_ds_msg_t ds_mach_0_11_nf = {
    182 	    CONV_DS_MSG_INIT(EM_NONE, mach_0_11_nf) };
    183 	static const conv_ds_msg_t ds_mach_0_11_dmp = {
    184 	    CONV_DS_MSG_INIT(EM_NONE, mach_0_11_dmp) };
    185 
    186 
    187 	static const Msg mach_15_22_cf[] = {
    188 		MSG_EM_PA_RISC_CF,	MSG_EM_NCUBE_CF,
    189 		MSG_EM_VPP500_CF,	MSG_EM_SPARC32PLUS_CF,
    190 		MSG_EM_960_CF,		MSG_EM_PPC_CF,
    191 		MSG_EM_PPC64_CF,	MSG_EM_S390_CF
    192 	};
    193 	static const Msg mach_15_22_nf[] = {
    194 		MSG_EM_PA_RISC_NF,	MSG_EM_NCUBE_NF,
    195 		MSG_EM_VPP500_NF,	MSG_EM_SPARC32PLUS_NF,
    196 		MSG_EM_960_NF,		MSG_EM_PPC_NF,
    197 		MSG_EM_PPC64_NF,	MSG_EM_S390_NF
    198 	};
    199 	static const Msg mach_15_22_dmp[] = {
    200 		MSG_EM_PA_RISC_DMP,	MSG_EM_NCUBE_DMP,
    201 		MSG_EM_VPP500_DMP,	MSG_EM_SPARC32PLUS_DMP,
    202 		MSG_EM_960_CF,		MSG_EM_PPC_DMP,
    203 		MSG_EM_PPC64_DMP,	MSG_EM_S390_CF
    204 	};
    205 	static const conv_ds_msg_t ds_mach_15_22_cf = {
    206 	    CONV_DS_MSG_INIT(EM_PA_RISC, mach_15_22_cf) };
    207 	static const conv_ds_msg_t ds_mach_15_22_nf = {
    208 	    CONV_DS_MSG_INIT(EM_PA_RISC, mach_15_22_nf) };
    209 	static const conv_ds_msg_t ds_mach_15_22_dmp = {
    210 	    CONV_DS_MSG_INIT(EM_PA_RISC, mach_15_22_dmp) };
    211 
    212 
    213 	static const Msg mach_36_63_cf[] = {
    214 		MSG_EM_V800_CF,		MSG_EM_FR20_CF,
    215 		MSG_EM_RH32_CF,		MSG_EM_RCE_CF,
    216 		MSG_EM_ARM_CF,		MSG_EM_ALPHA_CF,
    217 		MSG_EM_SH_CF,		MSG_EM_SPARCV9_CF,
    218 		MSG_EM_TRICORE_CF,	MSG_EM_ARC_CF,
    219 		MSG_EM_H8_300_CF,	MSG_EM_H8_300H_CF,
    220 		MSG_EM_H8S_CF,		MSG_EM_H8_500_CF,
    221 		MSG_EM_IA_64_CF,	MSG_EM_MIPS_X_CF,
    222 		MSG_EM_COLDFIRE_CF,	MSG_EM_68HC12_CF,
    223 		MSG_EM_MMA_CF,		MSG_EM_PCP_CF,
    224 		MSG_EM_NCPU_CF,		MSG_EM_NDR1_CF,
    225 		MSG_EM_STARCORE_CF,	MSG_EM_ME16_CF,
    226 		MSG_EM_ST100_CF,	MSG_EM_TINYJ_CF,
    227 		MSG_EM_AMD64_CF,	MSG_EM_PDSP_CF
    228 	};
    229 	static const Msg mach_36_63_nf[] = {
    230 		MSG_EM_V800_NF,		MSG_EM_FR20_NF,
    231 		MSG_EM_RH32_NF,		MSG_EM_RCE_NF,
    232 		MSG_EM_ARM_NF,		MSG_EM_ALPHA_NF,
    233 		MSG_EM_SH_NF,		MSG_EM_SPARCV9_NF,
    234 		MSG_EM_TRICORE_NF,	MSG_EM_ARC_NF,
    235 		MSG_EM_H8_300_NF,	MSG_EM_H8_300H_NF,
    236 		MSG_EM_H8S_NF,		MSG_EM_H8_500_NF,
    237 		MSG_EM_IA_64_NF,	MSG_EM_MIPS_X_NF,
    238 		MSG_EM_COLDFIRE_NF,	MSG_EM_68HC12_NF,
    239 		MSG_EM_MMA_NF,		MSG_EM_PCP_NF,
    240 		MSG_EM_NCPU_NF,		MSG_EM_NDR1_NF,
    241 		MSG_EM_STARCORE_NF,	MSG_EM_ME16_NF,
    242 		MSG_EM_ST100_NF,	MSG_EM_TINYJ_NF,
    243 		MSG_EM_AMD64_NF,	MSG_EM_PDSP_NF
    244 	};
    245 	static const Msg mach_36_63_dmp[] = {
    246 		MSG_EM_V800_CF,		MSG_EM_FR20_CF,
    247 		MSG_EM_RH32_CF,		MSG_EM_RCE_CF,
    248 		MSG_EM_ARM_DMP,		MSG_EM_ALPHA_DMP,
    249 		MSG_EM_SH_CF,		MSG_EM_SPARCV9_DMP,
    250 		MSG_EM_TRICORE_CF,	MSG_EM_ARC_CF,
    251 		MSG_EM_H8_300_CF,	MSG_EM_H8_300H_CF,
    252 		MSG_EM_H8S_CF,		MSG_EM_H8_500_CF,
    253 		MSG_EM_IA_64_DMP,	MSG_EM_MIPS_X_CF,
    254 		MSG_EM_COLDFIRE_CF,	MSG_EM_68HC12_CF,
    255 		MSG_EM_MMA_CF,		MSG_EM_PCP_CF,
    256 		MSG_EM_NCPU_CF,		MSG_EM_NDR1_CF,
    257 		MSG_EM_STARCORE_CF,	MSG_EM_ME16_CF,
    258 		MSG_EM_ST100_CF,	MSG_EM_TINYJ_CF,
    259 		MSG_EM_AMD64_DMP,	MSG_EM_PDSP_CF
    260 	};
    261 	static const conv_ds_msg_t ds_mach_36_63_cf = {
    262 	    CONV_DS_MSG_INIT(EM_V800, mach_36_63_cf) };
    263 	static const conv_ds_msg_t ds_mach_36_63_nf = {
    264 	    CONV_DS_MSG_INIT(EM_V800, mach_36_63_nf) };
    265 	static const conv_ds_msg_t ds_mach_36_63_dmp = {
    266 	    CONV_DS_MSG_INIT(EM_V800, mach_36_63_dmp) };
    267 
    268 
    269 	static const Msg mach_66_94_cf[] = {
    270 		MSG_EM_FX66_CF,		MSG_EM_ST9PLUS_CF,
    271 		MSG_EM_ST7_CF,		MSG_EM_68HC16_CF,
    272 		MSG_EM_68HC11_CF,	MSG_EM_68HC08_CF,
    273 		MSG_EM_68HC05_CF,	MSG_EM_SVX_CF,
    274 		MSG_EM_ST19_CF,		MSG_EM_VAX_CF,
    275 		MSG_EM_CRIS_CF,		MSG_EM_JAVELIN_CF,
    276 		MSG_EM_FIREPATH_CF,	MSG_EM_ZSP_CF,
    277 		MSG_EM_MMIX_CF,		MSG_EM_HUANY_CF,
    278 		MSG_EM_PRISM_CF,	MSG_EM_AVR_CF,
    279 		MSG_EM_FR30_CF,		MSG_EM_D10V_CF,
    280 		MSG_EM_D30V_CF,		MSG_EM_V850_CF,
    281 		MSG_EM_M32R_CF,		MSG_EM_MN10300_CF,
    282 		MSG_EM_MN10200_CF,	MSG_EM_PJ_CF,
    283 		MSG_EM_OPENRISC_CF,	MSG_EM_ARC_A5_CF,
    284 		MSG_EM_XTENSA_CF
    285 	};
    286 	static const Msg mach_66_94_nf[] = {
    287 		MSG_EM_FX66_NF,		MSG_EM_ST9PLUS_NF,
    288 		MSG_EM_ST7_NF,		MSG_EM_68HC16_NF,
    289 		MSG_EM_68HC11_NF,	MSG_EM_68HC08_NF,
    290 		MSG_EM_68HC05_NF,	MSG_EM_SVX_NF,
    291 		MSG_EM_ST19_NF,		MSG_EM_VAX_NF,
    292 		MSG_EM_CRIS_NF,		MSG_EM_JAVELIN_NF,
    293 		MSG_EM_FIREPATH_NF,	MSG_EM_ZSP_NF,
    294 		MSG_EM_MMIX_NF,		MSG_EM_HUANY_NF,
    295 		MSG_EM_PRISM_NF,	MSG_EM_AVR_NF,
    296 		MSG_EM_FR30_NF,		MSG_EM_D10V_NF,
    297 		MSG_EM_D30V_NF,		MSG_EM_V850_NF,
    298 		MSG_EM_M32R_NF,		MSG_EM_MN10300_NF,
    299 		MSG_EM_MN10200_NF,	MSG_EM_PJ_NF,
    300 		MSG_EM_OPENRISC_NF,	MSG_EM_ARC_A5_NF,
    301 		MSG_EM_XTENSA_NF
    302 	};
    303 	static const Msg mach_66_94_dmp[] = {
    304 		MSG_EM_FX66_CF,		MSG_EM_ST9PLUS_CF,
    305 		MSG_EM_ST7_CF,		MSG_EM_68HC16_CF,
    306 		MSG_EM_68HC11_CF,	MSG_EM_68HC08_CF,
    307 		MSG_EM_68HC05_CF,	MSG_EM_SVX_CF,
    308 		MSG_EM_ST19_CF,		MSG_EM_VAX_DMP,
    309 		MSG_EM_CRIS_CF,		MSG_EM_JAVELIN_CF,
    310 		MSG_EM_FIREPATH_CF,	MSG_EM_ZSP_CF,
    311 		MSG_EM_MMIX_CF,		MSG_EM_HUANY_CF,
    312 		MSG_EM_PRISM_CF,	MSG_EM_AVR_CF,
    313 		MSG_EM_FR30_CF,		MSG_EM_D10V_CF,
    314 		MSG_EM_D30V_CF,		MSG_EM_V850_CF,
    315 		MSG_EM_M32R_CF,		MSG_EM_MN10300_CF,
    316 		MSG_EM_MN10200_CF,	MSG_EM_PJ_CF,
    317 		MSG_EM_OPENRISC_CF,	MSG_EM_ARC_A5_CF,
    318 		MSG_EM_XTENSA_CF
    319 	};
    320 #if	(EM_NUM != (EM_XTENSA + 1))
    321 #error	"EM_NUM has grown"
    322 #endif
    323 	static const conv_ds_msg_t ds_mach_66_94_cf = {
    324 	    CONV_DS_MSG_INIT(EM_FX66, mach_66_94_cf) };
    325 	static const conv_ds_msg_t ds_mach_66_94_nf = {
    326 	    CONV_DS_MSG_INIT(EM_FX66, mach_66_94_nf) };
    327 	static const conv_ds_msg_t ds_mach_66_94_dmp = {
    328 	    CONV_DS_MSG_INIT(EM_FX66, mach_66_94_dmp) };
    329 
    330 
    331 	/* Build NULL terminated return arrays for each string style */
    332 	static const const conv_ds_t	*ds_cf[] = {
    333 		CONV_DS_ADDR(ds_mach_0_11_cf), CONV_DS_ADDR(ds_mach_15_22_cf),
    334 		CONV_DS_ADDR(ds_mach_36_63_cf), CONV_DS_ADDR(ds_mach_66_94_cf),
    335 		NULL
    336 	};
    337 	static const const conv_ds_t	*ds_nf[] = {
    338 		CONV_DS_ADDR(ds_mach_0_11_nf), CONV_DS_ADDR(ds_mach_15_22_nf),
    339 		CONV_DS_ADDR(ds_mach_36_63_nf), CONV_DS_ADDR(ds_mach_66_94_nf),
    340 		NULL
    341 	};
    342 	static const const conv_ds_t	*ds_dmp[] = {
    343 		CONV_DS_ADDR(ds_mach_0_11_dmp), CONV_DS_ADDR(ds_mach_15_22_dmp),
    344 		CONV_DS_ADDR(ds_mach_36_63_dmp),
    345 		CONV_DS_ADDR(ds_mach_66_94_dmp), NULL
    346 	};
    347 
    348 
    349 	/* Select the strings to use */
    350 	switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
    351 	case CONV_FMT_ALT_DUMP:
    352 	case CONV_FMT_ALT_FILE:
    353 		return (ds_dmp);
    354 	case CONV_FMT_ALT_NF:
    355 		return (ds_nf);
    356 	}
    357 
    358 	return (ds_cf);
    359 }
    360 
    361 const char *
    362 conv_ehdr_mach(Half machine, Conv_fmt_flags_t fmt_flags,
    363     Conv_inv_buf_t *inv_buf)
    364 {
    365 	return (conv_map_ds(ELFOSABI_NONE, EM_NONE, machine,
    366 	    ehdr_mach_strings(fmt_flags), fmt_flags, inv_buf));
    367 }
    368 
    369 conv_iter_ret_t
    370 conv_iter_ehdr_mach(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func,
    371     void *uvalue)
    372 {
    373 	static const Val_desc extra_dmp_nf[] = {
    374 		{ EM_M32,		MSG_EM_M32_DMP},
    375 		{ EM_386,		MSG_EM_386_DMP },
    376 		{ EM_68K,		MSG_EM_68K_DMP },
    377 		{ EM_88K,		MSG_EM_88K_DMP },
    378 		{ EM_486,		MSG_EM_486_DMP },
    379 		{ EM_860,		MSG_EM_860_DMP },
    380 		{ EM_MIPS,		MSG_EM_MIPS_DMP },
    381 		{ EM_MIPS_RS3_LE,	MSG_EM_MIPS_RS3_LE_DMP },
    382 		{ EM_PPC,		MSG_EM_PPC_DMP },
    383 		{ EM_PPC64,		MSG_EM_PPC64_DMP },
    384 
    385 		{ 0 }
    386 	};
    387 
    388 	if (conv_iter_ds(ELFOSABI_NONE, EM_NONE,
    389 	    ehdr_mach_strings(fmt_flags), func, uvalue) == CONV_ITER_DONE)
    390 		return (CONV_ITER_DONE);
    391 
    392 	/*
    393 	 * For the NF style, we also supply a few of the traditional
    394 	 * dump versions for iteration, but not for display.
    395 	 */
    396 	if (CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_NF)
    397 		return (conv_iter_vd(extra_dmp_nf, func, uvalue));
    398 
    399 	return (CONV_ITER_CONT);
    400 }
    401 
    402 
    403 
    404 static const conv_ds_t **
    405 ehdr_eident_strings(Conv_fmt_flags_t fmt_flags)
    406 {
    407 	static const Msg	eident_cf[] = {
    408 		MSG_EI_MAG0_CF,		MSG_EI_MAG1_CF,
    409 		MSG_EI_MAG2_CF,		MSG_EI_MAG3_CF,
    410 		MSG_EI_CLASS_CF,	MSG_EI_DATA_CF,
    411 		MSG_EI_VERSION_CF,	MSG_EI_OSABI_CF,
    412 		MSG_EI_ABIVERSION_CF
    413 	};
    414 	static const Msg	eident_nf[] = {
    415 		MSG_EI_MAG0_NF,		MSG_EI_MAG1_NF,
    416 		MSG_EI_MAG2_NF,		MSG_EI_MAG3_NF,
    417 		MSG_EI_CLASS_NF,	MSG_EI_DATA_NF,
    418 		MSG_EI_VERSION_NF,	MSG_EI_OSABI_NF,
    419 		MSG_EI_ABIVERSION_NF
    420 	};
    421 #if EI_PAD != (EI_ABIVERSION + 1)
    422 error "EI_PAD has grown. Update etypes[]"
    423 #endif
    424 	static const conv_ds_msg_t ds_eident_cf = {
    425 		CONV_DS_MSG_INIT(EI_MAG0, eident_cf) };
    426 	static const conv_ds_msg_t ds_eident_nf = {
    427 		CONV_DS_MSG_INIT(EI_MAG0, eident_nf) };
    428 
    429 	/* Build NULL terminated return arrays for each string style */
    430 	static const const conv_ds_t	*ds_cf[] = {
    431 		CONV_DS_ADDR(ds_eident_cf), NULL };
    432 	static const conv_ds_t	*ds_nf[] = {
    433 		CONV_DS_ADDR(ds_eident_nf), NULL };
    434 
    435 	/* Select the strings to use */
    436 	return ((CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_CF) ?
    437 	    ds_cf : ds_nf);
    438 }
    439 
    440 conv_iter_ret_t
    441 conv_iter_ehdr_eident(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func,
    442     void *uvalue)
    443 {
    444 	return (conv_iter_ds(ELFOSABI_NONE, EM_NONE,
    445 	    ehdr_eident_strings(fmt_flags), func, uvalue));
    446 }
    447 
    448 static const conv_ds_t **
    449 ehdr_type_strings(Conv_fmt_flags_t fmt_flags)
    450 {
    451 #define	SOL	ELFOSABI_SOLARIS, EM_NONE
    452 
    453 	static const Msg	type_cf[] = {
    454 		MSG_ET_NONE_CF,		MSG_ET_REL_CF,		MSG_ET_EXEC_CF,
    455 		MSG_ET_DYN_CF,		MSG_ET_CORE_CF
    456 	};
    457 	static const Msg	type_nf[] = {
    458 		MSG_ET_NONE_NF,		MSG_ET_REL_NF,		MSG_ET_EXEC_NF,
    459 		MSG_ET_DYN_NF,		MSG_ET_CORE_NF
    460 	};
    461 	static const Msg	type_dmp[] = {
    462 		MSG_ET_NONE_DMP,	MSG_ET_REL_DMP,		MSG_ET_EXEC_DMP,
    463 		MSG_ET_DYN_DMP,		MSG_ET_CORE_DMP
    464 	};
    465 #if ET_NUM != (ET_CORE + 1)
    466 error "ET_NUM has grown. Update types[]"
    467 #endif
    468 	static const conv_ds_msg_t ds_type_cf = {
    469 		CONV_DS_MSG_INIT(ET_NONE, type_cf) };
    470 	static const conv_ds_msg_t ds_type_nf = {
    471 		CONV_DS_MSG_INIT(ET_NONE, type_nf) };
    472 	static const conv_ds_msg_t ds_type_dmp = {
    473 		CONV_DS_MSG_INIT(ET_NONE, type_dmp) };
    474 
    475 	static const Val_desc2 type_osabi_cf[] = {
    476 		{ ET_SUNWPSEUDO,	SOL,	MSG_ET_SUNWPSEUDO_CF },
    477 		{ 0 }
    478 	};
    479 	static const Val_desc2 type_osabi_nf[] = {
    480 		{ ET_SUNWPSEUDO,	SOL,	MSG_ET_SUNWPSEUDO_NF },
    481 		{ 0 }
    482 	};
    483 	static const Val_desc2 type_osabi_dmp[] = {
    484 		{ ET_SUNWPSEUDO,	SOL,	MSG_ET_SUNWPSEUDO_DMP },
    485 		{ 0 }
    486 	};
    487 #if ET_LOSUNW != ET_SUNWPSEUDO
    488 error "ET_LOSUNW has grown. Update type_osabi[]"
    489 #endif
    490 	static const conv_ds_vd2_t ds_type_osabi_cf = {
    491 	    CONV_DS_VD2, ET_LOOS, ET_HIOS, type_osabi_cf };
    492 	static const conv_ds_vd2_t ds_type_osabi_nf = {
    493 	    CONV_DS_VD2, ET_LOOS, ET_HIOS, type_osabi_nf };
    494 	static const conv_ds_vd2_t ds_type_osabi_dmp = {
    495 	    CONV_DS_VD2, ET_LOOS, ET_HIOS, type_osabi_dmp };
    496 
    497 
    498 	/* Build NULL terminated return arrays for each string style */
    499 	static const const conv_ds_t	*ds_cf[] = {
    500 		CONV_DS_ADDR(ds_type_cf), CONV_DS_ADDR(ds_type_osabi_cf),
    501 		NULL };
    502 	static const conv_ds_t	*ds_nf[] = {
    503 		CONV_DS_ADDR(ds_type_nf), CONV_DS_ADDR(ds_type_osabi_nf),
    504 		NULL };
    505 	static const conv_ds_t	*ds_dmp[] = {
    506 		CONV_DS_ADDR(ds_type_dmp), CONV_DS_ADDR(ds_type_osabi_dmp),
    507 		NULL };
    508 
    509 	/* Select the strings to use */
    510 	switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
    511 	case CONV_FMT_ALT_DUMP:
    512 		return (ds_dmp);
    513 	case CONV_FMT_ALT_NF:
    514 		return (ds_nf);
    515 	}
    516 
    517 	return (ds_cf);
    518 
    519 #undef SOL
    520 }
    521 
    522 const char *
    523 conv_ehdr_type(uchar_t osabi, Half etype, Conv_fmt_flags_t fmt_flags,
    524     Conv_inv_buf_t *inv_buf)
    525 {
    526 	return (conv_map_ds(osabi, EM_NONE, etype,
    527 	    ehdr_type_strings(fmt_flags), fmt_flags, inv_buf));
    528 }
    529 
    530 conv_iter_ret_t
    531 conv_iter_ehdr_type(conv_iter_osabi_t osabi, Conv_fmt_flags_t fmt_flags,
    532     conv_iter_cb_t func, void *uvalue)
    533 {
    534 	return (conv_iter_ds(osabi, EM_NONE,
    535 	    ehdr_type_strings(fmt_flags), func, uvalue));
    536 }
    537 
    538 static const conv_ds_t **
    539 ehdr_vers_strings(Conv_fmt_flags_t fmt_flags)
    540 {
    541 	static const Msg	versions_cf[] = {
    542 		MSG_EV_NONE_CF,		MSG_EV_CURRENT_CF
    543 	};
    544 	static const Msg	versions_nf[] = {
    545 		MSG_EV_NONE_NF,		MSG_EV_CURRENT_NF
    546 	};
    547 	static const Msg	versions_dmp[] = {
    548 		MSG_EV_NONE_DMP,	MSG_EV_CURRENT_DMP
    549 	};
    550 #if EV_NUM != 2
    551 error "EV_NUM has grown. Update versions[]"
    552 #endif
    553 	static const conv_ds_msg_t ds_versions_cf = {
    554 		CONV_DS_MSG_INIT(EV_NONE, versions_cf) };
    555 	static const conv_ds_msg_t ds_versions_nf = {
    556 		CONV_DS_MSG_INIT(EV_NONE, versions_nf) };
    557 	static const conv_ds_msg_t ds_versions_dmp = {
    558 		CONV_DS_MSG_INIT(EV_NONE, versions_dmp) };
    559 
    560 	/* Build NULL terminated return arrays for each string style */
    561 	static const const conv_ds_t	*ds_cf[] = {
    562 		CONV_DS_ADDR(ds_versions_cf), NULL };
    563 	static const conv_ds_t	*ds_nf[] = {
    564 		CONV_DS_ADDR(ds_versions_nf), NULL };
    565 	static const conv_ds_t	*ds_dmp[] = {
    566 		CONV_DS_ADDR(ds_versions_dmp), NULL };
    567 
    568 	/* Select the strings to use */
    569 	switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
    570 	case CONV_FMT_ALT_DUMP:
    571 		return (ds_dmp);
    572 	case CONV_FMT_ALT_NF:
    573 		return (ds_nf);
    574 	}
    575 
    576 	return (ds_cf);
    577 }
    578 
    579 const char *
    580 conv_ehdr_vers(Word version, Conv_fmt_flags_t fmt_flags,
    581     Conv_inv_buf_t *inv_buf)
    582 {
    583 	return (conv_map_ds(ELFOSABI_NONE, EM_NONE, version,
    584 	    ehdr_vers_strings(fmt_flags), fmt_flags, inv_buf));
    585 }
    586 
    587 conv_iter_ret_t
    588 conv_iter_ehdr_vers(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func,
    589     void *uvalue)
    590 {
    591 	return (conv_iter_ds(ELFOSABI_NONE, EM_NONE,
    592 	    ehdr_vers_strings(fmt_flags), func, uvalue));
    593 }
    594 
    595 static void
    596 conv_ehdr_sparc_flags_strings(Conv_fmt_flags_t fmt_flags,
    597     const conv_ds_msg_t **mm_msg, const Val_desc **flag_desc)
    598 {
    599 #define	EFLAGSZ	CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
    600 	MSG_EF_SPARCV9_TSO_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE +  \
    601 	MSG_EF_SPARC_SUN_US1_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE +  \
    602 	MSG_EF_SPARC_HAL_R1_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE +  \
    603 	MSG_EF_SPARC_SUN_US3_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE +  \
    604 	CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
    605 
    606 	/*
    607 	 * Ensure that Conv_ehdr_flags_buf_t is large enough:
    608 	 *
    609 	 * EFLAGSZ is the real minimum size of the buffer required by
    610 	 * conv_ehdr_flags(). However, Conv_ehdr_flags_buf_t uses
    611 	 * CONV_EHDR_FLAG_BUFSIZE to set the buffer size. We do things
    612 	 * this way because the definition of EFLAGSZ uses information
    613 	 * that is not available in the environment of other programs
    614 	 * that include the conv.h header file.
    615 	 */
    616 #if (CONV_EHDR_FLAGS_BUFSIZE != EFLAGSZ) && !defined(__lint)
    617 #define	REPORT_BUFSIZE EFLAGSZ
    618 #include "report_bufsize.h"
    619 #error "CONV_EHDR_FLAGS_BUFSIZE does not match EFLAGSZ"
    620 #endif
    621 
    622 	static const Msg mm_flags_cf[] = {
    623 		MSG_EF_SPARCV9_TSO_CF,	MSG_EF_SPARCV9_PSO_CF,
    624 		MSG_EF_SPARCV9_RMO_CF
    625 	};
    626 	static const Msg mm_flags_nf[] = {
    627 		MSG_EF_SPARCV9_TSO_NF,	MSG_EF_SPARCV9_PSO_NF,
    628 		MSG_EF_SPARCV9_RMO_NF
    629 	};
    630 	static const conv_ds_msg_t ds_mm_flags_cf = {
    631 		CONV_DS_MSG_INIT(EF_SPARCV9_TSO, mm_flags_cf) };
    632 	static const conv_ds_msg_t ds_mm_flags_nf = {
    633 		CONV_DS_MSG_INIT(EF_SPARCV9_TSO, mm_flags_nf) };
    634 
    635 
    636 	static const Val_desc vda_cf[] = {
    637 		{ EF_SPARC_32PLUS,	MSG_EF_SPARC_32PLUS_CF },
    638 		{ EF_SPARC_SUN_US1,	MSG_EF_SPARC_SUN_US1_CF },
    639 		{ EF_SPARC_HAL_R1,	MSG_EF_SPARC_HAL_R1_CF },
    640 		{ EF_SPARC_SUN_US3,	MSG_EF_SPARC_SUN_US3_CF },
    641 		{ 0 }
    642 	};
    643 	static const Val_desc vda_nf[] = {
    644 		{ EF_SPARC_32PLUS,	MSG_EF_SPARC_32PLUS_NF },
    645 		{ EF_SPARC_SUN_US1,	MSG_EF_SPARC_SUN_US1_NF },
    646 		{ EF_SPARC_HAL_R1,	MSG_EF_SPARC_HAL_R1_NF },
    647 		{ EF_SPARC_SUN_US3,	MSG_EF_SPARC_SUN_US3_NF },
    648 		{ 0 }
    649 	};
    650 
    651 	switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
    652 	default:
    653 		*mm_msg = &ds_mm_flags_cf;
    654 		*flag_desc = vda_cf;
    655 		break;
    656 	case CONV_FMT_ALT_NF:
    657 		*mm_msg = &ds_mm_flags_nf;
    658 		*flag_desc = vda_nf;
    659 		break;
    660 	}
    661 }
    662 
    663 /*
    664  * Make a string representation of the e_flags field.
    665  */
    666 const char *
    667 conv_ehdr_flags(Half mach, Word flags, Conv_fmt_flags_t fmt_flags,
    668     Conv_ehdr_flags_buf_t *flags_buf)
    669 {
    670 	static const char *leading_str_arr[2];
    671 	static CONV_EXPN_FIELD_ARG conv_arg = {
    672 	    NULL, sizeof (flags_buf->buf), leading_str_arr };
    673 
    674 	const char **lstr;
    675 	const conv_ds_msg_t	*mm_msg;
    676 	const Val_desc		*vdp;
    677 	Word			mm;
    678 
    679 	/*
    680 	 * Non-SPARC architectures presently provide no known flags.
    681 	 */
    682 	if ((mach != EM_SPARCV9) && (((mach != EM_SPARC) &&
    683 	    (mach != EM_SPARC32PLUS)) || (flags == 0)))
    684 		return (conv_invalid_val(&flags_buf->inv_buf, flags,
    685 		    CONV_FMT_DECIMAL));
    686 
    687 	conv_arg.buf = flags_buf->buf;
    688 	conv_ehdr_sparc_flags_strings(fmt_flags, &mm_msg, &vdp);
    689 	conv_arg.oflags = conv_arg.rflags = flags;
    690 
    691 	mm = flags & EF_SPARCV9_MM;
    692 	lstr = leading_str_arr;
    693 	if ((mach == EM_SPARCV9) && (mm <= mm_msg->ds_topval)) {
    694 		*lstr++ = MSG_ORIG(mm_msg->ds_msg[mm]);
    695 		conv_arg.rflags &= ~EF_SPARCV9_MM;
    696 	}
    697 	*lstr = NULL;
    698 
    699 	(void) conv_expn_field(&conv_arg, vdp, fmt_flags);
    700 
    701 	return (conv_arg.buf);
    702 }
    703 
    704 conv_iter_ret_t
    705 conv_iter_ehdr_flags(Half mach, Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func,
    706     void *uvalue)
    707 {
    708 
    709 	if ((mach == EM_SPARCV9) || (mach == EM_SPARC) ||
    710 	    (mach == EM_SPARC32PLUS) || (mach == CONV_MACH_ALL)) {
    711 		const conv_ds_msg_t	*ds_msg_mm;
    712 		const Val_desc		*vdp;
    713 
    714 		conv_ehdr_sparc_flags_strings(fmt_flags, &ds_msg_mm, &vdp);
    715 
    716 		if (mach == EM_SPARCV9) {
    717 			const conv_ds_t *ds[2];
    718 
    719 			ds[0] = CONV_DS_ADDR(ds_msg_mm);
    720 			ds[1] = NULL;
    721 
    722 			if (conv_iter_ds(ELFOSABI_NONE, mach, ds,
    723 			    func, uvalue) == CONV_ITER_DONE)
    724 				return (CONV_ITER_DONE);
    725 		}
    726 
    727 		return (conv_iter_vd(vdp, func, uvalue));
    728 	}
    729 
    730 	return (CONV_ITER_CONT);
    731 }
    732 
    733 static const conv_ds_t **
    734 ehdr_osabi_strings(Conv_fmt_flags_t fmt_flags)
    735 {
    736 
    737 	static const Msg osabi_0_3_cf[] = {
    738 		MSG_OSABI_NONE_CF,	MSG_OSABI_HPUX_CF,
    739 		MSG_OSABI_NETBSD_CF,	MSG_OSABI_LINUX_CF
    740 	};
    741 	static const Msg osabi_0_3_nf[] = {
    742 		MSG_OSABI_NONE_NF,	MSG_OSABI_HPUX_NF,
    743 		MSG_OSABI_NETBSD_NF,	MSG_OSABI_LINUX_NF
    744 	};
    745 	static const Msg osabi_0_3_dmp[] = {
    746 		MSG_OSABI_NONE_DMP,	MSG_OSABI_HPUX_DMP,
    747 		MSG_OSABI_NETBSD_DMP,	MSG_OSABI_LINUX_DMP
    748 	};
    749 	static const conv_ds_msg_t ds_osabi_0_3_cf = {
    750 	    CONV_DS_MSG_INIT(ELFOSABI_NONE, osabi_0_3_cf) };
    751 	static const conv_ds_msg_t ds_osabi_0_3_nf = {
    752 	    CONV_DS_MSG_INIT(ELFOSABI_NONE, osabi_0_3_nf) };
    753 	static const conv_ds_msg_t ds_osabi_0_3_dmp = {
    754 	    CONV_DS_MSG_INIT(ELFOSABI_NONE, osabi_0_3_dmp) };
    755 
    756 
    757 	static const Msg osabi_6_15_cf[] = {
    758 		MSG_OSABI_SOLARIS_CF,	MSG_OSABI_AIX_CF,
    759 		MSG_OSABI_IRIX_CF,	MSG_OSABI_FREEBSD_CF,
    760 		MSG_OSABI_TRU64_CF,	MSG_OSABI_MODESTO_CF,
    761 		MSG_OSABI_OPENBSD_CF,	MSG_OSABI_OPENVMS_CF,
    762 		MSG_OSABI_NSK_CF,	MSG_OSABI_AROS_CF
    763 	};
    764 	static const Msg osabi_6_15_nf[] = {
    765 		MSG_OSABI_SOLARIS_NF,	MSG_OSABI_AIX_NF,
    766 		MSG_OSABI_IRIX_NF,	MSG_OSABI_FREEBSD_NF,
    767 		MSG_OSABI_TRU64_NF,	MSG_OSABI_MODESTO_NF,
    768 		MSG_OSABI_OPENBSD_NF,	MSG_OSABI_OPENVMS_NF,
    769 		MSG_OSABI_NSK_NF,	MSG_OSABI_AROS_NF
    770 	};
    771 	static const Msg osabi_6_15_dmp[] = {
    772 		MSG_OSABI_SOLARIS_DMP,	MSG_OSABI_AIX_DMP,
    773 		MSG_OSABI_IRIX_DMP,	MSG_OSABI_FREEBSD_DMP,
    774 		MSG_OSABI_TRU64_DMP,	MSG_OSABI_MODESTO_DMP,
    775 		MSG_OSABI_OPENBSD_DMP,	MSG_OSABI_OPENVMS_DMP,
    776 		MSG_OSABI_NSK_DMP,	MSG_OSABI_AROS_DMP
    777 	};
    778 	static const conv_ds_msg_t ds_osabi_6_15_cf = {
    779 	    CONV_DS_MSG_INIT(ELFOSABI_SOLARIS, osabi_6_15_cf) };
    780 	static const conv_ds_msg_t ds_osabi_6_15_nf = {
    781 	    CONV_DS_MSG_INIT(ELFOSABI_SOLARIS, osabi_6_15_nf) };
    782 	static const conv_ds_msg_t ds_osabi_6_15_dmp = {
    783 	    CONV_DS_MSG_INIT(ELFOSABI_SOLARIS, osabi_6_15_dmp) };
    784 
    785 
    786 	static const Val_desc osabi_misc_cf[] = {
    787 		{ ELFOSABI_ARM,			MSG_OSABI_ARM_CF },
    788 		{ ELFOSABI_STANDALONE,		MSG_OSABI_STANDALONE_CF },
    789 		{ 0 }
    790 	};
    791 	static const Val_desc osabi_misc_nf[] = {
    792 		{ ELFOSABI_ARM,			MSG_OSABI_ARM_NF },
    793 		{ ELFOSABI_STANDALONE,		MSG_OSABI_STANDALONE_NF },
    794 		{ 0 }
    795 	};
    796 	static const Val_desc osabi_misc_dmp[] = {
    797 		{ ELFOSABI_ARM,			MSG_OSABI_ARM_DMP },
    798 		{ ELFOSABI_STANDALONE,		MSG_OSABI_STANDALONE_DMP },
    799 		{ 0 }
    800 	};
    801 	static const conv_ds_vd_t ds_osabi_misc_cf = {
    802 	    CONV_DS_VD, ELFOSABI_ARM, ELFOSABI_STANDALONE, osabi_misc_cf };
    803 	static const conv_ds_vd_t ds_osabi_misc_nf = {
    804 	    CONV_DS_VD, ELFOSABI_ARM, ELFOSABI_STANDALONE, osabi_misc_nf };
    805 	static const conv_ds_vd_t ds_osabi_misc_dmp = {
    806 	    CONV_DS_VD, ELFOSABI_ARM, ELFOSABI_STANDALONE, osabi_misc_dmp };
    807 
    808 	/* Build NULL terminated return arrays for each string style */
    809 	static const const conv_ds_t	*ds_cf[] = {
    810 		CONV_DS_ADDR(ds_osabi_0_3_cf), CONV_DS_ADDR(ds_osabi_6_15_cf),
    811 		CONV_DS_ADDR(ds_osabi_misc_cf), NULL };
    812 	static const const conv_ds_t	*ds_nf[] = {
    813 		CONV_DS_ADDR(ds_osabi_0_3_nf), CONV_DS_ADDR(ds_osabi_6_15_nf),
    814 		CONV_DS_ADDR(ds_osabi_misc_nf), NULL };
    815 	static const const conv_ds_t	*ds_dmp[] = {
    816 		CONV_DS_ADDR(ds_osabi_0_3_dmp), CONV_DS_ADDR(ds_osabi_6_15_dmp),
    817 		CONV_DS_ADDR(ds_osabi_misc_dmp), NULL };
    818 
    819 	/* Select the strings to use */
    820 	switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
    821 	case CONV_FMT_ALT_DUMP:
    822 		return (ds_dmp);
    823 	case CONV_FMT_ALT_NF:
    824 		return (ds_nf);
    825 	}
    826 
    827 	return (ds_cf);
    828 }
    829 
    830 /*
    831  * Make a string representation of the e_ident[EI_OSABI] field.
    832  */
    833 const char *
    834 conv_ehdr_osabi(uchar_t osabi, Conv_fmt_flags_t fmt_flags,
    835     Conv_inv_buf_t *inv_buf)
    836 {
    837 	return (conv_map_ds(ELFOSABI_NONE, EM_NONE, osabi,
    838 	    ehdr_osabi_strings(fmt_flags), fmt_flags, inv_buf));
    839 }
    840 
    841 conv_iter_ret_t
    842 conv_iter_ehdr_osabi(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func,
    843     void *uvalue)
    844 {
    845 	if (conv_iter_ds(ELFOSABI_NONE, EM_NONE, ehdr_osabi_strings(fmt_flags),
    846 	    func, uvalue) == CONV_ITER_DONE)
    847 		return (CONV_ITER_DONE);
    848 
    849 	/*
    850 	 * ELFOSABI_NONE might have been better named ELFOSABI_SYSV. For the
    851 	 * CF and NF sytles, we supply that name for 0 in addition to NONE.
    852 	 */
    853 	switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
    854 	case CONV_FMT_ALT_CF:
    855 		return ((* func)(MSG_ORIG(MSG_OSABI_SYSV_CF),
    856 		    ELFOSABI_NONE, uvalue));
    857 	case CONV_FMT_ALT_NF:
    858 		return ((* func)(MSG_ORIG(MSG_OSABI_SYSV_NF),
    859 		    ELFOSABI_NONE, uvalue));
    860 	}
    861 
    862 		return (CONV_ITER_CONT);
    863 }
    864 
    865 static const conv_ds_t **
    866 ehdr_abivers_strings(conv_iter_osabi_t osabi, Conv_fmt_flags_t fmt_flags)
    867 {
    868 	static const Msg	abiversions_cf[] = {
    869 		MSG_EAV_SUNW_NONE_CF,	MSG_EAV_SUNW_CURRENT_CF
    870 	};
    871 	static const Msg	abiversions_nf[] = {
    872 		MSG_EAV_SUNW_NONE_NF,	MSG_EAV_SUNW_CURRENT_NF
    873 	};
    874 #if EAV_SUNW_NUM != 2
    875 error "EAV_SUNW_NUM has grown. Update abiversions[]"
    876 #endif
    877 	static const conv_ds_msg_t ds_abiversions_cf = {
    878 		CONV_DS_MSG_INIT(EV_NONE, abiversions_cf) };
    879 	static const conv_ds_msg_t ds_abiversions_nf = {
    880 		CONV_DS_MSG_INIT(EV_NONE, abiversions_nf) };
    881 
    882 	/* Build NULL terminated return arrays for each string style */
    883 	static const const conv_ds_t	*ds_cf[] = {
    884 		CONV_DS_ADDR(ds_abiversions_cf), NULL };
    885 	static const conv_ds_t	*ds_nf[] = {
    886 		CONV_DS_ADDR(ds_abiversions_nf), NULL };
    887 
    888 	/* For non-Solaris OSABI, we don't have symbolic names */
    889 	static const conv_ds_t	*ds_none[] = { NULL };
    890 
    891 
    892 	/*
    893 	 * Select the strings to use. This is a rare case where
    894 	 * we don't treat ELFOSABI_NONE and ELFOSABI_SOLARIS
    895 	 * as the same thing. We should never create a Solaris
    896 	 * object tagged as ELFOSABI_NONE for which the abiversion
    897 	 * is non-zero.
    898 	 */
    899 	if ((osabi == ELFOSABI_SOLARIS) || (osabi == CONV_OSABI_ALL))
    900 		return ((CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_NF) ?
    901 		    ds_nf : ds_cf);
    902 
    903 	return (ds_none);
    904 }
    905 
    906 const char *
    907 conv_ehdr_abivers(uchar_t osabi, Word version, Conv_fmt_flags_t fmt_flags,
    908     Conv_inv_buf_t *inv_buf)
    909 {
    910 	return (conv_map_ds(osabi, EM_NONE, version,
    911 	    ehdr_abivers_strings(osabi, fmt_flags), fmt_flags, inv_buf));
    912 }
    913 
    914 conv_iter_ret_t
    915 conv_iter_ehdr_abivers(conv_iter_osabi_t osabi, Conv_fmt_flags_t fmt_flags,
    916     conv_iter_cb_t func, void *uvalue)
    917 {
    918 	return (conv_iter_ds(osabi, EM_NONE,
    919 	    ehdr_abivers_strings(osabi, fmt_flags), func, uvalue));
    920 }
    921 
    922 /*
    923  * A generic means of returning additional information for a rejected file in
    924  * terms of a string. ELFOSABI_SOLARIS is assummed.
    925  */
    926 const char *
    927 conv_reject_desc(Rej_desc * rej, Conv_reject_desc_buf_t *reject_desc_buf,
    928     Half mach)
    929 {
    930 	ushort_t	type = rej->rej_type;
    931 	uint_t		info = rej->rej_info;
    932 
    933 	switch (type) {
    934 	case SGS_REJ_MACH:
    935 		return (conv_ehdr_mach((Half)info, 0,
    936 		    &reject_desc_buf->inv_buf));
    937 	case SGS_REJ_CLASS:
    938 		return (conv_ehdr_class((uchar_t)info, 0,
    939 		    &reject_desc_buf->inv_buf));
    940 	case SGS_REJ_DATA:
    941 		return (conv_ehdr_data((uchar_t)info, 0,
    942 		    &reject_desc_buf->inv_buf));
    943 	case SGS_REJ_TYPE:
    944 		return (conv_ehdr_type(ELFOSABI_SOLARIS, (Half)info, 0,
    945 		    &reject_desc_buf->inv_buf));
    946 	case SGS_REJ_BADFLAG:
    947 	case SGS_REJ_MISFLAG:
    948 	case SGS_REJ_HAL:
    949 	case SGS_REJ_US3:
    950 		return (conv_ehdr_flags(mach, (Word)info, 0,
    951 		    &reject_desc_buf->flags_buf));
    952 	case SGS_REJ_UNKFILE:
    953 		return ((const char *)0);
    954 	case SGS_REJ_STR:
    955 	case SGS_REJ_HWCAP_1:
    956 	case SGS_REJ_SFCAP_1:
    957 		if (rej->rej_str)
    958 			return ((const char *)rej->rej_str);
    959 		else
    960 			return (MSG_ORIG(MSG_STR_EMPTY));
    961 	default:
    962 		return (conv_invalid_val(&reject_desc_buf->inv_buf, info,
    963 		    CONV_FMT_DECIMAL));
    964 	}
    965 }
    966