xref: /illumos-gate/usr/src/cmd/sgs/libconv/common/elf.c (revision fb2a9bae0030340ad72b9c26ba1ffee2ee3cafec)
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 2010 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 	case SGS_REJ_HWCAP_2:
958 	case SGS_REJ_MACHCAP:
959 	case SGS_REJ_PLATCAP:
960 		if (rej->rej_str)
961 			return ((const char *)rej->rej_str);
962 		else
963 			return (MSG_ORIG(MSG_STR_EMPTY));
964 	default:
965 		return (conv_invalid_val(&reject_desc_buf->inv_buf, info,
966 		    CONV_FMT_DECIMAL));
967 	}
968 }
969