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