xref: /titanic_44/usr/src/cmd/sgs/libconv/common/sections.c (revision f6e214c7418f43af38bd8c3a557e3d0a1d311cfa)
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 section attributes.
29  */
30 #include	<string.h>
31 #include	<sys/param.h>
32 #include	<sys/elf_SPARC.h>
33 #include	<sys/elf_amd64.h>
34 #include	<_conv.h>
35 #include	<sections_msg.h>
36 
37 
38 static const conv_ds_t **
39 sec_type_strings(conv_iter_osabi_t osabi, Half mach, Conv_fmt_flags_t fmt_flags)
40 {
41 	/*
42 	 * This routine can return an array with 1 generic array, up to
43 	 * three osabi arrays, two machine arrays, plus the NULL termination.
44 	 */
45 #define	MAX_RET	7
46 
47 	static const Msg secs_def[SHT_NUM] = {
48 		MSG_SHT_NULL,			MSG_SHT_PROGBITS,
49 		MSG_SHT_SYMTAB,			MSG_SHT_STRTAB,
50 		MSG_SHT_RELA,			MSG_SHT_HASH,
51 		MSG_SHT_DYNAMIC,		MSG_SHT_NOTE,
52 		MSG_SHT_NOBITS,			MSG_SHT_REL,
53 		MSG_SHT_SHLIB,			MSG_SHT_DYNSYM,
54 		MSG_SHT_UNKNOWN12,		MSG_SHT_UNKNOWN13,
55 		MSG_SHT_INIT_ARRAY,		MSG_SHT_FINI_ARRAY,
56 		MSG_SHT_PREINIT_ARRAY,		MSG_SHT_GROUP,
57 		MSG_SHT_SYMTAB_SHNDX
58 	};
59 	static const Msg secs_dmp[SHT_NUM] = {
60 		MSG_SHT_NULL_DMP,		MSG_SHT_PROGBITS_DMP,
61 		MSG_SHT_SYMTAB_DMP,		MSG_SHT_STRTAB_DMP,
62 		MSG_SHT_RELA_DMP,		MSG_SHT_HASH_DMP,
63 		MSG_SHT_DYNAMIC_DMP,		MSG_SHT_NOTE_DMP,
64 		MSG_SHT_NOBITS_DMP,		MSG_SHT_REL_DMP,
65 		MSG_SHT_SHLIB_DMP,		MSG_SHT_DYNSYM_DMP,
66 		MSG_SHT_UNKNOWN12_DMP,		MSG_SHT_UNKNOWN13_DMP,
67 		MSG_SHT_INIT_ARRAY_DMP,		MSG_SHT_FINI_ARRAY_DMP,
68 		MSG_SHT_PREINIT_ARRAY_DMP,	MSG_SHT_GROUP_DMP,
69 		MSG_SHT_SYMTAB_SHNDX_DMP
70 	};
71 	static const Msg secs_cf[SHT_NUM] = {
72 		MSG_SHT_NULL_CF,		MSG_SHT_PROGBITS_CF,
73 		MSG_SHT_SYMTAB_CF,		MSG_SHT_STRTAB_CF,
74 		MSG_SHT_RELA_CF,		MSG_SHT_HASH_CF,
75 		MSG_SHT_DYNAMIC_CF,		MSG_SHT_NOTE_CF,
76 		MSG_SHT_NOBITS_CF,		MSG_SHT_REL_CF,
77 		MSG_SHT_SHLIB_CF,		MSG_SHT_DYNSYM_CF,
78 		MSG_SHT_UNKNOWN12_CF,		MSG_SHT_UNKNOWN13_CF,
79 		MSG_SHT_INIT_ARRAY_CF,		MSG_SHT_FINI_ARRAY_CF,
80 		MSG_SHT_PREINIT_ARRAY_CF,	MSG_SHT_GROUP_CF,
81 		MSG_SHT_SYMTAB_SHNDX_CF
82 	};
83 	static const Msg secs_nf[SHT_NUM] = {
84 		MSG_SHT_NULL_NF,		MSG_SHT_PROGBITS_NF,
85 		MSG_SHT_SYMTAB_NF,		MSG_SHT_STRTAB_NF,
86 		MSG_SHT_RELA_NF,		MSG_SHT_HASH_NF,
87 		MSG_SHT_DYNAMIC_NF,		MSG_SHT_NOTE_NF,
88 		MSG_SHT_NOBITS_NF,		MSG_SHT_REL_NF,
89 		MSG_SHT_SHLIB_NF,		MSG_SHT_DYNSYM_NF,
90 		MSG_SHT_UNKNOWN12_NF,		MSG_SHT_UNKNOWN13_NF,
91 		MSG_SHT_INIT_ARRAY_NF,		MSG_SHT_FINI_ARRAY_NF,
92 		MSG_SHT_PREINIT_ARRAY_NF,	MSG_SHT_GROUP_NF,
93 		MSG_SHT_SYMTAB_SHNDX_NF
94 	};
95 #if	(SHT_NUM != (SHT_SYMTAB_SHNDX + 1))
96 #error	"SHT_NUM has grown"
97 #endif
98 	static const conv_ds_msg_t ds_secs_def = {
99 	    CONV_DS_MSG_INIT(SHT_NULL, secs_def) };
100 	static const conv_ds_msg_t ds_secs_dmp = {
101 	    CONV_DS_MSG_INIT(SHT_NULL, secs_dmp) };
102 	static const conv_ds_msg_t ds_secs_cf = {
103 	    CONV_DS_MSG_INIT(SHT_NULL, secs_cf) };
104 	static const conv_ds_msg_t ds_secs_nf = {
105 	    CONV_DS_MSG_INIT(SHT_NULL, secs_nf) };
106 
107 
108 	static const Msg usecs_def[SHT_HISUNW - SHT_LOSUNW + 1] = {
109 		MSG_SHT_SUNW_CAPCHAIN,		MSG_SHT_SUNW_CAPINFO,
110 		MSG_SHT_SUNW_SYMSORT,		MSG_SHT_SUNW_TLSSORT,
111 		MSG_SHT_SUNW_LDYNSYM,		MSG_SHT_SUNW_DOF,
112 		MSG_SHT_SUNW_CAP,		MSG_SHT_SUNW_SIGNATURE,
113 		MSG_SHT_SUNW_ANNOTATE,		MSG_SHT_SUNW_DEBUGSTR,
114 		MSG_SHT_SUNW_DEBUG,		MSG_SHT_SUNW_MOVE,
115 		MSG_SHT_SUNW_COMDAT,		MSG_SHT_SUNW_SYMINFO,
116 		MSG_SHT_SUNW_VERDEF,		MSG_SHT_SUNW_VERNEED,
117 		MSG_SHT_SUNW_VERSYM
118 	};
119 	static const Msg usecs_dmp[SHT_HISUNW - SHT_LOSUNW + 1] = {
120 		MSG_SHT_SUNW_CAPCHAIN_DMP,	MSG_SHT_SUNW_CAPINFO_DMP,
121 		MSG_SHT_SUNW_SYMSORT_DMP,	MSG_SHT_SUNW_TLSSORT_DMP,
122 		MSG_SHT_SUNW_LDYNSYM_DMP,	MSG_SHT_SUNW_DOF_DMP,
123 		MSG_SHT_SUNW_CAP_DMP,		MSG_SHT_SUNW_SIGNATURE_DMP,
124 		MSG_SHT_SUNW_ANNOTATE_DMP,	MSG_SHT_SUNW_DEBUGSTR_DMP,
125 		MSG_SHT_SUNW_DEBUG_DMP,		MSG_SHT_SUNW_MOVE_DMP,
126 		MSG_SHT_SUNW_COMDAT_DMP,	MSG_SHT_SUNW_SYMINFO_DMP,
127 		MSG_SHT_SUNW_VERDEF_DMP,	MSG_SHT_SUNW_VERNEED_DMP,
128 		MSG_SHT_SUNW_VERSYM_DMP
129 	};
130 	static const Msg usecs_cf[SHT_HISUNW - SHT_LOSUNW + 1] = {
131 		MSG_SHT_SUNW_CAPCHAIN_CF,	MSG_SHT_SUNW_CAPINFO_CF,
132 		MSG_SHT_SUNW_SYMSORT_CF,	MSG_SHT_SUNW_TLSSORT_CF,
133 		MSG_SHT_SUNW_LDYNSYM_CF,	MSG_SHT_SUNW_DOF_CF,
134 		MSG_SHT_SUNW_CAP_CF,		MSG_SHT_SUNW_SIGNATURE_CF,
135 		MSG_SHT_SUNW_ANNOTATE_CF,	MSG_SHT_SUNW_DEBUGSTR_CF,
136 		MSG_SHT_SUNW_DEBUG_CF,		MSG_SHT_SUNW_MOVE_CF,
137 		MSG_SHT_SUNW_COMDAT_CF,		MSG_SHT_SUNW_SYMINFO_CF,
138 		MSG_SHT_SUNW_VERDEF_CF,		MSG_SHT_SUNW_VERNEED_CF,
139 		MSG_SHT_SUNW_VERSYM_CF
140 	};
141 	static const Msg usecs_nf[SHT_HISUNW - SHT_LOSUNW + 1] = {
142 		MSG_SHT_SUNW_CAPCHAIN_NF,	MSG_SHT_SUNW_CAPINFO_NF,
143 		MSG_SHT_SUNW_SYMSORT_NF,	MSG_SHT_SUNW_TLSSORT_NF,
144 		MSG_SHT_SUNW_LDYNSYM_NF,	MSG_SHT_SUNW_DOF_NF,
145 		MSG_SHT_SUNW_CAP_NF,		MSG_SHT_SUNW_SIGNATURE_NF,
146 		MSG_SHT_SUNW_ANNOTATE_NF,	MSG_SHT_SUNW_DEBUGSTR_NF,
147 		MSG_SHT_SUNW_DEBUG_NF,		MSG_SHT_SUNW_MOVE_NF,
148 		MSG_SHT_SUNW_COMDAT_NF,		MSG_SHT_SUNW_SYMINFO_NF,
149 		MSG_SHT_SUNW_VERDEF_NF,		MSG_SHT_SUNW_VERNEED_NF,
150 		MSG_SHT_SUNW_VERSYM_NF
151 	};
152 #if	(SHT_LOSUNW != SHT_SUNW_capchain)
153 #error	"SHT_LOSUNW has moved"
154 #endif
155 	static const conv_ds_msg_t ds_usecs_def = {
156 	    CONV_DS_MSG_INIT(SHT_SUNW_capchain, usecs_def) };
157 	static const conv_ds_msg_t ds_usecs_dmp = {
158 	    CONV_DS_MSG_INIT(SHT_SUNW_capchain, usecs_dmp) };
159 	static const conv_ds_msg_t ds_usecs_cf = {
160 	    CONV_DS_MSG_INIT(SHT_SUNW_capchain, usecs_cf) };
161 	static const conv_ds_msg_t ds_usecs_nf = {
162 	    CONV_DS_MSG_INIT(SHT_SUNW_capchain, usecs_nf) };
163 
164 
165 	/* The Linux osabi range has two separate sequences */
166 	static const Msg usecs_gnu1_def[] = {
167 		MSG_SHT_GNU_ATTRIBUTES,		MSG_SHT_GNU_HASH,
168 		MSG_SHT_GNU_LIBLIST,		MSG_SHT_CHECKSUM,
169 	};
170 	static const Msg usecs_gnu1_dmp[] = {
171 		MSG_SHT_GNU_ATTRIBUTES_DMP,	MSG_SHT_GNU_HASH_DMP,
172 		MSG_SHT_GNU_LIBLIST_DMP,	MSG_SHT_CHECKSUM_DMP,
173 	};
174 	static const Msg usecs_gnu1_cf[] = {
175 		MSG_SHT_GNU_ATTRIBUTES_CF,	MSG_SHT_GNU_HASH_CF,
176 		MSG_SHT_GNU_LIBLIST_CF,	MSG_SHT_CHECKSUM_CF,
177 	};
178 	static const Msg usecs_gnu1_nf[] = {
179 		MSG_SHT_GNU_ATTRIBUTES_NF,	MSG_SHT_GNU_HASH_NF,
180 		MSG_SHT_GNU_LIBLIST_NF,	MSG_SHT_CHECKSUM_NF,
181 	};
182 	static const conv_ds_msg_t ds_usecs_gnu1_def = {
183 	    CONV_DS_MSG_INIT(SHT_GNU_ATTRIBUTES, usecs_gnu1_def) };
184 	static const conv_ds_msg_t ds_usecs_gnu1_dmp = {
185 	    CONV_DS_MSG_INIT(SHT_GNU_ATTRIBUTES, usecs_gnu1_dmp) };
186 	static const conv_ds_msg_t ds_usecs_gnu1_cf = {
187 	    CONV_DS_MSG_INIT(SHT_GNU_ATTRIBUTES, usecs_gnu1_cf) };
188 	static const conv_ds_msg_t ds_usecs_gnu1_nf = {
189 	    CONV_DS_MSG_INIT(SHT_GNU_ATTRIBUTES, usecs_gnu1_nf) };
190 
191 
192 	static const Msg usecs_gnu2_def[] = {
193 		MSG_SHT_GNU_VERDEF,		MSG_SHT_GNU_VERNEED,
194 		MSG_SHT_GNU_VERSYM
195 	};
196 	static const Msg usecs_gnu2_dmp[] = {
197 		MSG_SHT_GNU_VERDEF_DMP,		MSG_SHT_GNU_VERNEED_DMP,
198 		MSG_SHT_GNU_VERSYM_DMP
199 	};
200 	static const Msg usecs_gnu2_cf[] = {
201 		MSG_SHT_GNU_VERDEF_CF,		MSG_SHT_GNU_VERNEED_CF,
202 		MSG_SHT_GNU_VERSYM_CF
203 	};
204 	static const Msg usecs_gnu2_nf[] = {
205 		MSG_SHT_GNU_VERDEF_NF,		MSG_SHT_GNU_VERNEED_NF,
206 		MSG_SHT_GNU_VERSYM_NF
207 	};
208 	static const conv_ds_msg_t ds_usecs_gnu2_def = {
209 	    CONV_DS_MSG_INIT(SHT_GNU_verdef, usecs_gnu2_def) };
210 	static const conv_ds_msg_t ds_usecs_gnu2_dmp = {
211 	    CONV_DS_MSG_INIT(SHT_GNU_verdef, usecs_gnu2_dmp) };
212 	static const conv_ds_msg_t ds_usecs_gnu2_cf = {
213 	    CONV_DS_MSG_INIT(SHT_GNU_verdef, usecs_gnu2_cf) };
214 	static const conv_ds_msg_t ds_usecs_gnu2_nf = {
215 	    CONV_DS_MSG_INIT(SHT_GNU_verdef, usecs_gnu2_nf) };
216 
217 
218 	/* sparc processor range */
219 	static const Msg sparc_def[] = { MSG_SHT_SPARC_GOTDATA };
220 	static const Msg sparc_dmp[] = { MSG_SHT_SPARC_GOTDATA_DMP };
221 	static const Msg sparc_cf[] = { MSG_SHT_SPARC_GOTDATA_CF };
222 	static const Msg sparc_nf[] = { MSG_SHT_SPARC_GOTDATA_NF };
223 	static const conv_ds_msg_t ds_sparc_def = {
224 	    CONV_DS_MSG_INIT(SHT_SPARC_GOTDATA, sparc_def) };
225 	static const conv_ds_msg_t ds_sparc_dmp = {
226 	    CONV_DS_MSG_INIT(SHT_SPARC_GOTDATA, sparc_dmp) };
227 	static const conv_ds_msg_t ds_sparc_cf = {
228 	    CONV_DS_MSG_INIT(SHT_SPARC_GOTDATA, sparc_cf) };
229 	static const conv_ds_msg_t ds_sparc_nf = {
230 	    CONV_DS_MSG_INIT(SHT_SPARC_GOTDATA, sparc_nf) };
231 
232 	/* amd64 processor range */
233 	static const Msg amd64_def[] = { MSG_SHT_AMD64_UNWIND };
234 	static const Msg amd64_dmp[] = { MSG_SHT_AMD64_UNWIND_DMP };
235 	static const Msg amd64_cf[] = { MSG_SHT_AMD64_UNWIND_CF };
236 	static const Msg amd64_nf[] = { MSG_SHT_AMD64_UNWIND_NF };
237 	static const conv_ds_msg_t ds_amd64_def = {
238 	    CONV_DS_MSG_INIT(SHT_AMD64_UNWIND, amd64_def) };
239 	static const conv_ds_msg_t ds_amd64_dmp = {
240 	    CONV_DS_MSG_INIT(SHT_AMD64_UNWIND, amd64_dmp) };
241 	static const conv_ds_msg_t ds_amd64_cf = {
242 	    CONV_DS_MSG_INIT(SHT_AMD64_UNWIND, amd64_cf) };
243 	static const conv_ds_msg_t ds_amd64_nf = {
244 	    CONV_DS_MSG_INIT(SHT_AMD64_UNWIND, amd64_nf) };
245 
246 
247 	static const conv_ds_t	*retarr[MAX_RET];
248 	int			retndx = 0;
249 
250 	/* Select the strings to use, based on string style and OSABI */
251 	switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
252 	case CONV_FMT_ALT_DUMP:
253 		retarr[retndx++] = CONV_DS_ADDR(ds_secs_dmp);
254 		break;
255 	case CONV_FMT_ALT_CF:
256 		retarr[retndx++] = CONV_DS_ADDR(ds_secs_cf);
257 		break;
258 	case CONV_FMT_ALT_NF:
259 		retarr[retndx++] = CONV_DS_ADDR(ds_secs_nf);
260 		break;
261 	default:
262 		retarr[retndx++] = CONV_DS_ADDR(ds_secs_def);
263 		break;
264 	}
265 
266 	if ((osabi == ELFOSABI_NONE) || (osabi == ELFOSABI_SOLARIS) ||
267 	    (osabi == CONV_OSABI_ALL)) {
268 		switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
269 		case CONV_FMT_ALT_DUMP:
270 			retarr[retndx++] = CONV_DS_ADDR(ds_usecs_dmp);
271 			break;
272 		case CONV_FMT_ALT_CF:
273 			retarr[retndx++] = CONV_DS_ADDR(ds_usecs_cf);
274 			break;
275 		case CONV_FMT_ALT_NF:
276 			retarr[retndx++] = CONV_DS_ADDR(ds_usecs_nf);
277 			break;
278 		default:
279 			retarr[retndx++] = CONV_DS_ADDR(ds_usecs_def);
280 			break;
281 		}
282 	}
283 
284 	if ((osabi == ELFOSABI_LINUX) || (osabi == CONV_OSABI_ALL)) {
285 		switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
286 		case CONV_FMT_ALT_DUMP:
287 			retarr[retndx++] = CONV_DS_ADDR(ds_usecs_gnu1_dmp);
288 			retarr[retndx++] = CONV_DS_ADDR(ds_usecs_gnu2_dmp);
289 			break;
290 		case CONV_FMT_ALT_CF:
291 			retarr[retndx++] = CONV_DS_ADDR(ds_usecs_gnu1_cf);
292 			retarr[retndx++] = CONV_DS_ADDR(ds_usecs_gnu2_cf);
293 			break;
294 		case CONV_FMT_ALT_NF:
295 			retarr[retndx++] = CONV_DS_ADDR(ds_usecs_gnu1_nf);
296 			retarr[retndx++] = CONV_DS_ADDR(ds_usecs_gnu2_nf);
297 			break;
298 		default:
299 			retarr[retndx++] = CONV_DS_ADDR(ds_usecs_gnu1_def);
300 			retarr[retndx++] = CONV_DS_ADDR(ds_usecs_gnu2_def);
301 			break;
302 		}
303 	}
304 
305 	if ((mach == EM_SPARC) || (mach == EM_SPARC32PLUS) ||
306 	    (mach == EM_SPARCV9) || (mach == CONV_MACH_ALL)) {
307 		switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
308 		case CONV_FMT_ALT_DUMP:
309 			retarr[retndx++] = CONV_DS_ADDR(ds_sparc_dmp);
310 			break;
311 		case CONV_FMT_ALT_CF:
312 			retarr[retndx++] = CONV_DS_ADDR(ds_sparc_cf);
313 			break;
314 		case CONV_FMT_ALT_NF:
315 			retarr[retndx++] = CONV_DS_ADDR(ds_sparc_nf);
316 			break;
317 		default:
318 			retarr[retndx++] = CONV_DS_ADDR(ds_sparc_def);
319 			break;
320 		}
321 	}
322 
323 	if ((mach == EM_AMD64) || (mach == CONV_MACH_ALL)) {
324 		switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
325 		case CONV_FMT_ALT_DUMP:
326 			retarr[retndx++] = CONV_DS_ADDR(ds_amd64_dmp);
327 			break;
328 		case CONV_FMT_ALT_CF:
329 			retarr[retndx++] = CONV_DS_ADDR(ds_amd64_cf);
330 			break;
331 		case CONV_FMT_ALT_NF:
332 			retarr[retndx++] = CONV_DS_ADDR(ds_amd64_nf);
333 			break;
334 		default:
335 			retarr[retndx++] = CONV_DS_ADDR(ds_amd64_def);
336 			break;
337 		}
338 	}
339 
340 	retarr[retndx++] = NULL;
341 	assert(retndx <= MAX_RET);
342 	return (retarr);
343 
344 #undef MAX_RET
345 }
346 
347 const char *
348 conv_sec_type(uchar_t osabi, Half mach, Word sec, Conv_fmt_flags_t fmt_flags,
349     Conv_inv_buf_t *inv_buf)
350 {
351 	return (conv_map_ds(osabi, mach, sec,
352 	    sec_type_strings(osabi, mach, fmt_flags), fmt_flags, inv_buf));
353 }
354 
355 conv_iter_ret_t
356 conv_iter_sec_type(conv_iter_osabi_t osabi, Half mach,
357     Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func, void *uvalue)
358 {
359 	return (conv_iter_ds(osabi, mach,
360 	    sec_type_strings(osabi, mach, fmt_flags), func, uvalue));
361 }
362 
363 
364 /*
365  * Special iteration routine that returns strings for all symbol table
366  * sections.
367  */
368 conv_iter_ret_t
369 conv_iter_sec_symtab(conv_iter_osabi_t osabi, Conv_fmt_flags_t fmt_flags,
370     conv_iter_cb_t func, void *uvalue)
371 {
372 	static const Val_desc2 symtab_cf[] = {
373 		{ SHT_SYMTAB,	0, 0,	MSG_SHT_SYMTAB_CF },
374 		{ SHT_DYNSYM,	0, 0,	MSG_SHT_DYNSYM_CF },
375 		{ SHT_SUNW_LDYNSYM, ELFOSABI_SOLARIS, 0,
376 					MSG_SHT_SUNW_LDYNSYM_CF },
377 
378 		{ 0 }
379 	};
380 	static const Val_desc2 symtab_nf[] = {
381 		{ SHT_SYMTAB,	0, 0,	MSG_SHT_SYMTAB_NF },
382 		{ SHT_DYNSYM,	0, 0,	MSG_SHT_DYNSYM_NF },
383 		{ SHT_SUNW_LDYNSYM, ELFOSABI_SOLARIS, 0,
384 					MSG_SHT_SUNW_LDYNSYM_NF },
385 
386 		{ 0 }
387 	};
388 
389 	const Val_desc2 *vdp;
390 
391 	vdp = (CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_NF) ?
392 	    symtab_nf : symtab_cf;
393 
394 	return (conv_iter_vd2(osabi, EM_NONE, vdp, func, uvalue));
395 }
396 
397 
398 const Val_desc2 *
399 conv_sec_flags_strings(Conv_fmt_flags_t fmt_flags)
400 {
401 #define	FLAGSZ	CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
402 	MSG_SHF_WRITE_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
403 	MSG_SHF_ALLOC_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
404 	MSG_SHF_EXECINSTR_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
405 	MSG_SHF_MERGE_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
406 	MSG_SHF_STRINGS_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
407 	MSG_SHF_INFO_LINK_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
408 	MSG_SHF_LINK_ORDER_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
409 	MSG_SHF_OS_NONCONFORMING_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
410 	MSG_SHF_GROUP_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
411 	MSG_SHF_TLS_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
412 	MSG_SHF_EXCLUDE_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
413 	MSG_SHF_ORDERED_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
414 	MSG_SHF_AMD64_LARGE_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
415 	CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
416 
417 	/*
418 	 * Ensure that Conv_sec_flags_buf_t is large enough:
419 	 *
420 	 * FLAGSZ is the real minimum size of the buffer required by
421 	 * conv_sec_flags(). However, Conv_sec_flags_buf_t uses
422 	 * CONV_SEC_FLAGS_BUFSIZE to set the buffer size. We do things this
423 	 * way because the definition of FLAGSZ uses information that is not
424 	 * available in the environment of other programs that include the
425 	 * conv.h header file.
426 	 */
427 #if (CONV_SEC_FLAGS_BUFSIZE != FLAGSZ) && !defined(__lint)
428 #define	REPORT_BUFSIZE FLAGSZ
429 #include "report_bufsize.h"
430 #error "CONV_SEC_FLAGS_BUFSIZE does not match FLAGSZ"
431 #endif
432 
433 #define	ALL	ELFOSABI_NONE, EM_NONE
434 #define	SOL	ELFOSABI_SOLARIS, EM_NONE
435 #define	AMD	ELFOSABI_NONE, EM_AMD64
436 
437 	static const Val_desc2 vda_cf[] = {
438 		{ SHF_WRITE,		ALL,	MSG_SHF_WRITE_CF },
439 		{ SHF_ALLOC,		ALL,	MSG_SHF_ALLOC_CF },
440 		{ SHF_EXECINSTR,	ALL,	MSG_SHF_EXECINSTR_CF },
441 		{ SHF_MERGE,		ALL,	MSG_SHF_MERGE_CF },
442 		{ SHF_STRINGS,		ALL,	MSG_SHF_STRINGS_CF },
443 		{ SHF_INFO_LINK,	ALL,	MSG_SHF_INFO_LINK_CF },
444 		{ SHF_LINK_ORDER,	ALL,	MSG_SHF_LINK_ORDER_CF },
445 		{ SHF_OS_NONCONFORMING,	ALL,	MSG_SHF_OS_NONCONFORMING_CF },
446 		{ SHF_GROUP,		ALL,	MSG_SHF_GROUP_CF },
447 		{ SHF_TLS,		ALL,	MSG_SHF_TLS_CF },
448 		{ SHF_EXCLUDE,		SOL,	MSG_SHF_EXCLUDE_CF },
449 		{ SHF_ORDERED,		SOL,	MSG_SHF_ORDERED_CF },
450 		{ SHF_AMD64_LARGE,	AMD,	MSG_SHF_AMD64_LARGE_CF },
451 		{ 0,			0 }
452 	};
453 	static const Val_desc2 vda_nf[] = {
454 		{ SHF_WRITE,		ALL,	MSG_SHF_WRITE_NF },
455 		{ SHF_ALLOC,		ALL,	MSG_SHF_ALLOC_NF },
456 		{ SHF_EXECINSTR,	ALL,	MSG_SHF_EXECINSTR_NF },
457 		{ SHF_MERGE,		ALL,	MSG_SHF_MERGE_NF },
458 		{ SHF_STRINGS,		ALL,	MSG_SHF_STRINGS_NF },
459 		{ SHF_INFO_LINK,	ALL,	MSG_SHF_INFO_LINK_NF },
460 		{ SHF_LINK_ORDER,	ALL,	MSG_SHF_LINK_ORDER_NF },
461 		{ SHF_OS_NONCONFORMING,	ALL,	MSG_SHF_OS_NONCONFORMING_NF },
462 		{ SHF_GROUP,		ALL,	MSG_SHF_GROUP_NF },
463 		{ SHF_TLS,		ALL,	MSG_SHF_TLS_NF },
464 		{ SHF_EXCLUDE,		SOL,	MSG_SHF_EXCLUDE_NF },
465 		{ SHF_ORDERED,		SOL,	MSG_SHF_ORDERED_NF },
466 		{ SHF_AMD64_LARGE,	AMD,	MSG_SHF_AMD64_LARGE_NF },
467 		{ 0,			0 }
468 	};
469 
470 	return ((CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_NF) ?
471 	    vda_nf : vda_cf);
472 
473 #undef ALL
474 #undef SOL
475 #undef AMD
476 }
477 
478 conv_iter_ret_t
479 conv_iter_sec_flags(conv_iter_osabi_t osabi, Half mach,
480     Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func, void *uvalue)
481 {
482 	static const Msg amd64_alias_cf[] = { MSG_SHF_X86_64_LARGE_CF };
483 	static const conv_ds_msg_t ds_msg_amd64_alias_cf = {
484 	    CONV_DS_MSG_INIT(SHF_X86_64_LARGE, amd64_alias_cf) };
485 	static const conv_ds_t	*ds_amd64_alias_cf[] = {
486 	    CONV_DS_ADDR(ds_msg_amd64_alias_cf), NULL };
487 
488 	static const Msg amd64_alias_nf[] = { MSG_SHF_X86_64_LARGE_NF };
489 	static const conv_ds_msg_t ds_msg_amd64_alias_nf = {
490 	    CONV_DS_MSG_INIT(SHF_X86_64_LARGE, amd64_alias_nf) };
491 	static const conv_ds_t	*ds_amd64_alias_nf[] = {
492 	    CONV_DS_ADDR(ds_msg_amd64_alias_nf), NULL };
493 
494 
495 	if (conv_iter_vd2(osabi, mach, conv_sec_flags_strings(fmt_flags),
496 	    func, uvalue) == CONV_ITER_DONE)
497 		return (CONV_ITER_DONE);
498 
499 	/* SHF_AMD64_LARGE is also known as SHF_X86_64_LARGE */
500 	if (mach == EM_AMD64) {
501 		const conv_ds_t **ds;
502 
503 		ds = (CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_NF) ?
504 		    ds_amd64_alias_nf : ds_amd64_alias_cf;
505 
506 		return (conv_iter_ds(ELFOSABI_NONE, mach, ds, func, uvalue));
507 	}
508 
509 	return (CONV_ITER_CONT);
510 }
511