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 **
sec_type_strings(conv_iter_osabi_t osabi,Half mach,Conv_fmt_flags_t fmt_flags)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 	 * four osabi arrays, two machine arrays, plus the NULL termination.
44 	 */
45 #define	MAX_RET	8
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 	/* LLVM "OS-specific" range */
247 	static const Msg llvm_def[] = {
248 		MSG_SHT_LLVM_ODRTAB,	MSG_SHT_LLVM_LINKER_OPTIONS,
249 		MSG_SHT_LLVM_UNKNOWN1,
250 		MSG_SHT_LLVM_ADDRSIG,	MSG_SHT_LLVM_DEPENDENT_LIBRARIES,
251 		MSG_SHT_LLVM_SYMPART,	MSG_SHT_LLVM_PART_EHDR,
252 		MSG_SHT_LLVM_PART_PHDR,	MSG_SHT_LLVM_BB_ADDR_MAP,
253 		MSG_SHT_LLVM_CALL_GRAPH_PROFILE
254 	};
255 	static const Msg llvm_dmp[] = {
256 		MSG_SHT_LLVM_ODRTAB_DMP,	MSG_SHT_LLVM_LINKER_OPTIONS_DMP,
257 		MSG_SHT_LLVM_UNKNOWN1_DMP,	MSG_SHT_LLVM_ADDRSIG_DMP,
258 		MSG_SHT_LLVM_DEPENDENT_LIBRARIES_DMP,
259 		MSG_SHT_LLVM_SYMPART_DMP,	MSG_SHT_LLVM_PART_EHDR_DMP,
260 		MSG_SHT_LLVM_PART_PHDR_DMP,	MSG_SHT_LLVM_BB_ADDR_MAP_DMP,
261 		MSG_SHT_LLVM_CALL_GRAPH_PROFILE_DMP
262 	};
263 	static const Msg llvm_cf[] = {
264 		MSG_SHT_LLVM_ODRTAB_CF,		MSG_SHT_LLVM_LINKER_OPTIONS_CF,
265 		MSG_SHT_LLVM_UNKNOWN1_CF,	MSG_SHT_LLVM_ADDRSIG_CF,
266 		MSG_SHT_LLVM_DEPENDENT_LIBRARIES_CF,
267 		MSG_SHT_LLVM_SYMPART_CF,	MSG_SHT_LLVM_PART_EHDR_CF,
268 		MSG_SHT_LLVM_PART_PHDR_CF,	MSG_SHT_LLVM_BB_ADDR_MAP_CF,
269 		MSG_SHT_LLVM_CALL_GRAPH_PROFILE_CF
270 	};
271 	static const Msg llvm_nf[] = {
272 		MSG_SHT_LLVM_ODRTAB_NF,		MSG_SHT_LLVM_LINKER_OPTIONS_NF,
273 		MSG_SHT_LLVM_UNKNOWN1_NF,	MSG_SHT_LLVM_ADDRSIG_NF,
274 		MSG_SHT_LLVM_DEPENDENT_LIBRARIES_NF,
275 		MSG_SHT_LLVM_SYMPART_NF,	MSG_SHT_LLVM_PART_EHDR_NF,
276 		MSG_SHT_LLVM_PART_PHDR_NF,	MSG_SHT_LLVM_BB_ADDR_MAP_NF,
277 		MSG_SHT_LLVM_CALL_GRAPH_PROFILE_NF
278 	};
279 
280 	static const conv_ds_msg_t ds_llvm_def = {
281 		CONV_DS_MSG_INIT(SHT_LLVM_ODRTAB, llvm_def) };
282 	static const conv_ds_msg_t ds_llvm_dmp = {
283 		CONV_DS_MSG_INIT(SHT_LLVM_ODRTAB, llvm_dmp) };
284 	static const conv_ds_msg_t ds_llvm_cf = {
285 		CONV_DS_MSG_INIT(SHT_LLVM_ODRTAB, llvm_cf) };
286 	static const conv_ds_msg_t ds_llvm_nf = {
287 		CONV_DS_MSG_INIT(SHT_LLVM_ODRTAB, llvm_nf) };
288 
289 	static const conv_ds_t	*retarr[MAX_RET];
290 	int			retndx = 0;
291 
292 	/* Select the strings to use, based on string style and OSABI */
293 	switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
294 	case CONV_FMT_ALT_DUMP:
295 		retarr[retndx++] = CONV_DS_ADDR(ds_secs_dmp);
296 		break;
297 	case CONV_FMT_ALT_CF:
298 		retarr[retndx++] = CONV_DS_ADDR(ds_secs_cf);
299 		break;
300 	case CONV_FMT_ALT_NF:
301 		retarr[retndx++] = CONV_DS_ADDR(ds_secs_nf);
302 		break;
303 	default:
304 		retarr[retndx++] = CONV_DS_ADDR(ds_secs_def);
305 		break;
306 	}
307 
308 	if ((osabi == ELFOSABI_NONE) || (osabi == ELFOSABI_SOLARIS) ||
309 	    (osabi == CONV_OSABI_ALL)) {
310 		switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
311 		case CONV_FMT_ALT_DUMP:
312 			retarr[retndx++] = CONV_DS_ADDR(ds_usecs_dmp);
313 			break;
314 		case CONV_FMT_ALT_CF:
315 			retarr[retndx++] = CONV_DS_ADDR(ds_usecs_cf);
316 			break;
317 		case CONV_FMT_ALT_NF:
318 			retarr[retndx++] = CONV_DS_ADDR(ds_usecs_nf);
319 			break;
320 		default:
321 			retarr[retndx++] = CONV_DS_ADDR(ds_usecs_def);
322 			break;
323 		}
324 	}
325 
326 	if ((osabi == ELFOSABI_NONE) || (osabi == ELFOSABI_LINUX) ||
327 	    (osabi == ELFOSABI_SOLARIS) || (osabi == CONV_OSABI_ALL)) {
328 		switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
329 		case CONV_FMT_ALT_DUMP:
330 			retarr[retndx++] = CONV_DS_ADDR(ds_llvm_dmp);
331 			break;
332 		case CONV_FMT_ALT_CF:
333 			retarr[retndx++] = CONV_DS_ADDR(ds_llvm_cf);
334 			break;
335 		case CONV_FMT_ALT_NF:
336 			retarr[retndx++] = CONV_DS_ADDR(ds_llvm_nf);
337 			break;
338 		default:
339 			retarr[retndx++] = CONV_DS_ADDR(ds_llvm_def);
340 			break;
341 		}
342 	}
343 
344 	if ((osabi == ELFOSABI_LINUX) || (osabi == CONV_OSABI_ALL)) {
345 		switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
346 		case CONV_FMT_ALT_DUMP:
347 			retarr[retndx++] = CONV_DS_ADDR(ds_usecs_gnu1_dmp);
348 			retarr[retndx++] = CONV_DS_ADDR(ds_usecs_gnu2_dmp);
349 			break;
350 		case CONV_FMT_ALT_CF:
351 			retarr[retndx++] = CONV_DS_ADDR(ds_usecs_gnu1_cf);
352 			retarr[retndx++] = CONV_DS_ADDR(ds_usecs_gnu2_cf);
353 			break;
354 		case CONV_FMT_ALT_NF:
355 			retarr[retndx++] = CONV_DS_ADDR(ds_usecs_gnu1_nf);
356 			retarr[retndx++] = CONV_DS_ADDR(ds_usecs_gnu2_nf);
357 			break;
358 		default:
359 			retarr[retndx++] = CONV_DS_ADDR(ds_usecs_gnu1_def);
360 			retarr[retndx++] = CONV_DS_ADDR(ds_usecs_gnu2_def);
361 			break;
362 		}
363 	}
364 
365 	if ((mach == EM_SPARC) || (mach == EM_SPARC32PLUS) ||
366 	    (mach == EM_SPARCV9) || (mach == CONV_MACH_ALL)) {
367 		switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
368 		case CONV_FMT_ALT_DUMP:
369 			retarr[retndx++] = CONV_DS_ADDR(ds_sparc_dmp);
370 			break;
371 		case CONV_FMT_ALT_CF:
372 			retarr[retndx++] = CONV_DS_ADDR(ds_sparc_cf);
373 			break;
374 		case CONV_FMT_ALT_NF:
375 			retarr[retndx++] = CONV_DS_ADDR(ds_sparc_nf);
376 			break;
377 		default:
378 			retarr[retndx++] = CONV_DS_ADDR(ds_sparc_def);
379 			break;
380 		}
381 	}
382 
383 	if ((mach == EM_AMD64) || (mach == CONV_MACH_ALL)) {
384 		switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
385 		case CONV_FMT_ALT_DUMP:
386 			retarr[retndx++] = CONV_DS_ADDR(ds_amd64_dmp);
387 			break;
388 		case CONV_FMT_ALT_CF:
389 			retarr[retndx++] = CONV_DS_ADDR(ds_amd64_cf);
390 			break;
391 		case CONV_FMT_ALT_NF:
392 			retarr[retndx++] = CONV_DS_ADDR(ds_amd64_nf);
393 			break;
394 		default:
395 			retarr[retndx++] = CONV_DS_ADDR(ds_amd64_def);
396 			break;
397 		}
398 	}
399 
400 	retarr[retndx++] = NULL;
401 	assert(retndx <= MAX_RET);
402 	return (retarr);
403 
404 #undef MAX_RET
405 }
406 
407 const char *
conv_sec_type(uchar_t osabi,Half mach,Word sec,Conv_fmt_flags_t fmt_flags,Conv_inv_buf_t * inv_buf)408 conv_sec_type(uchar_t osabi, Half mach, Word sec, Conv_fmt_flags_t fmt_flags,
409     Conv_inv_buf_t *inv_buf)
410 {
411 	return (conv_map_ds(osabi, mach, sec,
412 	    sec_type_strings(osabi, mach, fmt_flags), fmt_flags, inv_buf));
413 }
414 
415 conv_iter_ret_t
conv_iter_sec_type(conv_iter_osabi_t osabi,Half mach,Conv_fmt_flags_t fmt_flags,conv_iter_cb_t func,void * uvalue)416 conv_iter_sec_type(conv_iter_osabi_t osabi, Half mach,
417     Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func, void *uvalue)
418 {
419 	return (conv_iter_ds(osabi, mach,
420 	    sec_type_strings(osabi, mach, fmt_flags), func, uvalue));
421 }
422 
423 
424 /*
425  * Special iteration routine that returns strings for all symbol table
426  * sections.
427  */
428 conv_iter_ret_t
conv_iter_sec_symtab(conv_iter_osabi_t osabi,Conv_fmt_flags_t fmt_flags,conv_iter_cb_t func,void * uvalue)429 conv_iter_sec_symtab(conv_iter_osabi_t osabi, Conv_fmt_flags_t fmt_flags,
430     conv_iter_cb_t func, void *uvalue)
431 {
432 	static const Val_desc2 symtab_cf[] = {
433 		{ SHT_SYMTAB,	0, 0,	MSG_SHT_SYMTAB_CF },
434 		{ SHT_DYNSYM,	0, 0,	MSG_SHT_DYNSYM_CF },
435 		{ SHT_SUNW_LDYNSYM, ELFOSABI_SOLARIS, 0,
436 					MSG_SHT_SUNW_LDYNSYM_CF },
437 
438 		{ 0 }
439 	};
440 	static const Val_desc2 symtab_nf[] = {
441 		{ SHT_SYMTAB,	0, 0,	MSG_SHT_SYMTAB_NF },
442 		{ SHT_DYNSYM,	0, 0,	MSG_SHT_DYNSYM_NF },
443 		{ SHT_SUNW_LDYNSYM, ELFOSABI_SOLARIS, 0,
444 					MSG_SHT_SUNW_LDYNSYM_NF },
445 
446 		{ 0 }
447 	};
448 
449 	const Val_desc2 *vdp;
450 
451 	vdp = (CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_NF) ?
452 	    symtab_nf : symtab_cf;
453 
454 	return (conv_iter_vd2(osabi, EM_NONE, vdp, func, uvalue));
455 }
456 
457 
458 const Val_desc2 *
conv_sec_flags_strings(Conv_fmt_flags_t fmt_flags)459 conv_sec_flags_strings(Conv_fmt_flags_t fmt_flags)
460 {
461 #define	FLAGSZ	CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
462 	MSG_SHF_WRITE_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
463 	MSG_SHF_ALLOC_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
464 	MSG_SHF_EXECINSTR_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
465 	MSG_SHF_MERGE_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
466 	MSG_SHF_STRINGS_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
467 	MSG_SHF_INFO_LINK_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
468 	MSG_SHF_LINK_ORDER_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
469 	MSG_SHF_OS_NONCONFORMING_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
470 	MSG_SHF_GROUP_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
471 	MSG_SHF_TLS_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
472 	MSG_SHF_EXCLUDE_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
473 	MSG_SHF_ORDERED_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
474 	MSG_SHF_AMD64_LARGE_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
475 	CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
476 
477 	/*
478 	 * Ensure that Conv_sec_flags_buf_t is large enough:
479 	 *
480 	 * FLAGSZ is the real minimum size of the buffer required by
481 	 * conv_sec_flags(). However, Conv_sec_flags_buf_t uses
482 	 * CONV_SEC_FLAGS_BUFSIZE to set the buffer size. We do things this
483 	 * way because the definition of FLAGSZ uses information that is not
484 	 * available in the environment of other programs that include the
485 	 * conv.h header file.
486 	 */
487 #if (CONV_SEC_FLAGS_BUFSIZE != FLAGSZ) && !defined(__lint)
488 #define	REPORT_BUFSIZE FLAGSZ
489 #include "report_bufsize.h"
490 #error "CONV_SEC_FLAGS_BUFSIZE does not match FLAGSZ"
491 #endif
492 
493 #define	ALL	ELFOSABI_NONE, EM_NONE
494 #define	SOL	ELFOSABI_SOLARIS, EM_NONE
495 #define	AMD	ELFOSABI_NONE, EM_AMD64
496 
497 	static const Val_desc2 vda_cf[] = {
498 		{ SHF_WRITE,		ALL,	MSG_SHF_WRITE_CF },
499 		{ SHF_ALLOC,		ALL,	MSG_SHF_ALLOC_CF },
500 		{ SHF_EXECINSTR,	ALL,	MSG_SHF_EXECINSTR_CF },
501 		{ SHF_MERGE,		ALL,	MSG_SHF_MERGE_CF },
502 		{ SHF_STRINGS,		ALL,	MSG_SHF_STRINGS_CF },
503 		{ SHF_INFO_LINK,	ALL,	MSG_SHF_INFO_LINK_CF },
504 		{ SHF_LINK_ORDER,	ALL,	MSG_SHF_LINK_ORDER_CF },
505 		{ SHF_OS_NONCONFORMING,	ALL,	MSG_SHF_OS_NONCONFORMING_CF },
506 		{ SHF_GROUP,		ALL,	MSG_SHF_GROUP_CF },
507 		{ SHF_TLS,		ALL,	MSG_SHF_TLS_CF },
508 		{ SHF_EXCLUDE,		SOL,	MSG_SHF_EXCLUDE_CF },
509 		{ SHF_ORDERED,		SOL,	MSG_SHF_ORDERED_CF },
510 		{ SHF_AMD64_LARGE,	AMD,	MSG_SHF_AMD64_LARGE_CF },
511 		{ 0,			0 }
512 	};
513 	static const Val_desc2 vda_nf[] = {
514 		{ SHF_WRITE,		ALL,	MSG_SHF_WRITE_NF },
515 		{ SHF_ALLOC,		ALL,	MSG_SHF_ALLOC_NF },
516 		{ SHF_EXECINSTR,	ALL,	MSG_SHF_EXECINSTR_NF },
517 		{ SHF_MERGE,		ALL,	MSG_SHF_MERGE_NF },
518 		{ SHF_STRINGS,		ALL,	MSG_SHF_STRINGS_NF },
519 		{ SHF_INFO_LINK,	ALL,	MSG_SHF_INFO_LINK_NF },
520 		{ SHF_LINK_ORDER,	ALL,	MSG_SHF_LINK_ORDER_NF },
521 		{ SHF_OS_NONCONFORMING,	ALL,	MSG_SHF_OS_NONCONFORMING_NF },
522 		{ SHF_GROUP,		ALL,	MSG_SHF_GROUP_NF },
523 		{ SHF_TLS,		ALL,	MSG_SHF_TLS_NF },
524 		{ SHF_EXCLUDE,		SOL,	MSG_SHF_EXCLUDE_NF },
525 		{ SHF_ORDERED,		SOL,	MSG_SHF_ORDERED_NF },
526 		{ SHF_AMD64_LARGE,	AMD,	MSG_SHF_AMD64_LARGE_NF },
527 		{ 0,			0 }
528 	};
529 
530 	return ((CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_NF) ?
531 	    vda_nf : vda_cf);
532 
533 #undef ALL
534 #undef SOL
535 #undef AMD
536 }
537 
538 conv_iter_ret_t
conv_iter_sec_flags(conv_iter_osabi_t osabi,Half mach,Conv_fmt_flags_t fmt_flags,conv_iter_cb_t func,void * uvalue)539 conv_iter_sec_flags(conv_iter_osabi_t osabi, Half mach,
540     Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func, void *uvalue)
541 {
542 	static const Msg amd64_alias_cf[] = { MSG_SHF_X86_64_LARGE_CF };
543 	static const conv_ds_msg_t ds_msg_amd64_alias_cf = {
544 	    CONV_DS_MSG_INIT(SHF_X86_64_LARGE, amd64_alias_cf) };
545 	static const conv_ds_t	*ds_amd64_alias_cf[] = {
546 	    CONV_DS_ADDR(ds_msg_amd64_alias_cf), NULL };
547 
548 	static const Msg amd64_alias_nf[] = { MSG_SHF_X86_64_LARGE_NF };
549 	static const conv_ds_msg_t ds_msg_amd64_alias_nf = {
550 	    CONV_DS_MSG_INIT(SHF_X86_64_LARGE, amd64_alias_nf) };
551 	static const conv_ds_t	*ds_amd64_alias_nf[] = {
552 	    CONV_DS_ADDR(ds_msg_amd64_alias_nf), NULL };
553 
554 
555 	if (conv_iter_vd2(osabi, mach, conv_sec_flags_strings(fmt_flags),
556 	    func, uvalue) == CONV_ITER_DONE)
557 		return (CONV_ITER_DONE);
558 
559 	/* SHF_AMD64_LARGE is also known as SHF_X86_64_LARGE */
560 	if (mach == EM_AMD64) {
561 		const conv_ds_t **ds;
562 
563 		ds = (CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_NF) ?
564 		    ds_amd64_alias_nf : ds_amd64_alias_cf;
565 
566 		return (conv_iter_ds(ELFOSABI_NONE, mach, ds, func, uvalue));
567 	}
568 
569 	return (CONV_ITER_CONT);
570 }
571