xref: /illumos-gate/usr/src/cmd/sgs/libconv/common/dynamic.c (revision 8a2b682e57a046b828f37bcde1776f131ef4629f)
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 routine for .dynamic tag entries.
28  */
29 #include	<stdio.h>
30 #include	<string.h>
31 #include	<sys/elf_SPARC.h>
32 #include	"rtld.h"
33 #include	"_conv.h"
34 #include	"dynamic_msg.h"
35 
36 
37 
38 const Val_desc *
39 conv_dyn_posflag1_strings(Conv_fmt_flags_t fmt_flags)
40 {
41 #define	POSSZ	CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
42 	MSG_DF_P1_LAZYLOAD_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
43 	MSG_DF_P1_GROUPPERM_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
44 	MSG_DF_P1_DEFERRED_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
45 	CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
46 
47 	/*
48 	 * Ensure that Conv_dyn_posflag1_buf_t is large enough:
49 	 *
50 	 * POSSZ is the real minimum size of the buffer required by
51 	 * conv_dyn_posflag1(). However, Conv_dyn_posflag1_buf_t uses
52 	 * CONV_DYN_POSFLAG1_BUFSIZE to set the buffer size. We do things
53 	 * this way because the definition of POSSZ uses
54 	 * information that is not available in the environment of other
55 	 * programs that include the conv.h header file.
56 	 */
57 #if (CONV_DYN_POSFLAG1_BUFSIZE != POSSZ) && !defined(__lint)
58 #define	REPORT_BUFSIZE POSSZ
59 #include "report_bufsize.h"
60 #error "CONV_DYN_POSFLAG1_BUFSIZE does not match POSSZ"
61 #endif
62 
63 	static const Val_desc vda_def[] = {
64 		{ DF_P1_LAZYLOAD,	MSG_DF_P1_LAZYLOAD_DEF },
65 		{ DF_P1_GROUPPERM,	MSG_DF_P1_GROUPPERM_DEF },
66 		{ DF_P1_DEFERRED,	MSG_DF_P1_DEFERRED_DEF },
67 		{ 0,			0 }
68 	};
69 	static const Val_desc vda_cf[] = {
70 		{ DF_P1_LAZYLOAD,	MSG_DF_P1_LAZYLOAD_CF },
71 		{ DF_P1_GROUPPERM,	MSG_DF_P1_GROUPPERM_CF },
72 		{ DF_P1_DEFERRED,	MSG_DF_P1_DEFERRED_CF },
73 		{ 0,			0 }
74 	};
75 	static const Val_desc vda_cfnp[] = {
76 		{ DF_P1_LAZYLOAD,	MSG_DF_P1_LAZYLOAD_CFNP },
77 		{ DF_P1_GROUPPERM,	MSG_DF_P1_GROUPPERM_CFNP },
78 		{ DF_P1_DEFERRED,	MSG_DF_P1_DEFERRED_CFNP },
79 		{ 0,			0 }
80 	};
81 	static const Val_desc vda_nf[] = {
82 		{ DF_P1_LAZYLOAD,	MSG_DF_P1_LAZYLOAD_NF },
83 		{ DF_P1_GROUPPERM,	MSG_DF_P1_GROUPPERM_NF },
84 		{ DF_P1_DEFERRED,	MSG_DF_P1_DEFERRED_NF },
85 		{ 0,			0 }
86 	};
87 
88 	switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
89 	case CONV_FMT_ALT_DUMP:
90 	case CONV_FMT_ALT_CFNP:
91 		return (vda_cfnp);
92 	case CONV_FMT_ALT_CF:
93 		return (vda_cf);
94 	case CONV_FMT_ALT_NF:
95 		return (vda_nf);
96 	}
97 
98 	return (vda_def);
99 }
100 
101 conv_iter_ret_t
102 conv_iter_dyn_posflag1(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func,
103     void *uvalue)
104 {
105 	return (conv_iter_vd(conv_dyn_posflag1_strings(fmt_flags),
106 	    func, uvalue));
107 }
108 
109 const Val_desc *
110 conv_dyn_flag_strings(Conv_fmt_flags_t fmt_flags)
111 {
112 #define	FLAGSZ	CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
113 	MSG_DF_ORIGIN_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
114 	MSG_DF_SYMBOLIC_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
115 	MSG_DF_TEXTREL_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
116 	MSG_DF_BIND_NOW_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
117 	MSG_DF_STATIC_TLS_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
118 	CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
119 
120 	/*
121 	 * Ensure that Conv_dyn_flag_buf_t is large enough:
122 	 *
123 	 * FLAGSZ is the real minimum size of the buffer required by
124 	 * conv_dyn_flag(). However, Conv_dyn_flag_buf_t uses
125 	 * CONV_DYN_FLAG_BUFSIZE to set the buffer size. We do things this
126 	 * way because the definition of FLAGSZ uses information that is not
127 	 * available in the environment of other programs that include the
128 	 * conv.h header file.
129 	 */
130 #if (CONV_DYN_FLAG_BUFSIZE != FLAGSZ) && !defined(__lint)
131 #define	REPORT_BUFSIZE FLAGSZ
132 #include "report_bufsize.h"
133 #error "CONV_DYN_FLAG_BUFSIZE does not match FLAGSZ"
134 #endif
135 
136 	static const Val_desc vda_cf[] = {
137 		{ DF_ORIGIN,		MSG_DF_ORIGIN_CF },
138 		{ DF_SYMBOLIC,		MSG_DF_SYMBOLIC_CF },
139 		{ DF_TEXTREL,		MSG_DF_TEXTREL_CF },
140 		{ DF_BIND_NOW,		MSG_DF_BIND_NOW_CF },
141 		{ DF_STATIC_TLS,	MSG_DF_STATIC_TLS_CF },
142 		{ 0 }
143 	};
144 	static const Val_desc vda_cfnp[] = {
145 		{ DF_ORIGIN,		MSG_DF_ORIGIN_CFNP },
146 		{ DF_SYMBOLIC,		MSG_DF_SYMBOLIC_CFNP },
147 		{ DF_TEXTREL,		MSG_DF_TEXTREL_CFNP },
148 		{ DF_BIND_NOW,		MSG_DF_BIND_NOW_CFNP },
149 		{ DF_STATIC_TLS,	MSG_DF_STATIC_TLS_CFNP },
150 		{ 0 }
151 	};
152 	static const Val_desc vda_nf[] = {
153 		{ DF_ORIGIN,		MSG_DF_ORIGIN_NF },
154 		{ DF_SYMBOLIC,		MSG_DF_SYMBOLIC_NF },
155 		{ DF_TEXTREL,		MSG_DF_TEXTREL_NF },
156 		{ DF_BIND_NOW,		MSG_DF_BIND_NOW_NF },
157 		{ DF_STATIC_TLS,	MSG_DF_STATIC_TLS_NF },
158 		{ 0 }
159 	};
160 
161 	switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
162 	case CONV_FMT_ALT_CF:
163 		return (vda_cf);
164 	case CONV_FMT_ALT_NF:
165 		return (vda_nf);
166 	}
167 
168 	return (vda_cfnp);
169 }
170 
171 conv_iter_ret_t
172 conv_iter_dyn_flag(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func,
173     void *uvalue)
174 {
175 	return (conv_iter_vd(conv_dyn_flag_strings(fmt_flags), func, uvalue));
176 }
177 
178 const Val_desc *
179 conv_dyn_flag1_strings(Conv_fmt_flags_t fmt_flags)
180 {
181 #define	FLAG1SZ	CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
182 	MSG_DF_1_NOW_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
183 	MSG_DF_1_GLOBAL_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
184 	MSG_DF_1_GROUP_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
185 	MSG_DF_1_NODELETE_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
186 	MSG_DF_1_LOADFLTR_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
187 	MSG_DF_1_INITFIRST_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
188 	MSG_DF_1_NOOPEN_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
189 	MSG_DF_1_ORIGIN_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
190 	MSG_DF_1_DIRECT_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
191 	MSG_DF_1_TRANS_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
192 	MSG_DF_1_INTERPOSE_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
193 	MSG_DF_1_NODEFLIB_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
194 	MSG_DF_1_NODUMP_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
195 	MSG_DF_1_CONFALT_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
196 	MSG_DF_1_ENDFILTEE_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
197 	MSG_DF_1_DISPRELPND_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
198 	MSG_DF_1_DISPRELDNE_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
199 	MSG_DF_1_NODIRECT_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
200 	MSG_DF_1_IGNMULDEF_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
201 	MSG_DF_1_NOKSYMS_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
202 	MSG_DF_1_NOHDR_CF_SIZE		+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
203 	MSG_DF_1_NORELOC_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
204 	MSG_DF_1_SYMINTPOSE_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
205 	MSG_DF_1_GLOBAUDIT_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
206 	MSG_DF_1_SINGLETON_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
207 	CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
208 
209 	/*
210 	 * Ensure that Conv_dyn_flag1_buf_t is large enough:
211 	 *
212 	 * FLAG1SZ is the real minimum size of the buffer required by
213 	 * conv_dyn_flag1(). However, Conv_dyn_flag1_buf_t uses
214 	 * CONV_DYN_FLAG1_BUFSIZE to set the buffer size. We do things this
215 	 * way because the definition of FLAG1SZ uses information that is not
216 	 * available in the environment of other programs that include the
217 	 * conv.h header file.
218 	 */
219 #if (CONV_DYN_FLAG1_BUFSIZE != FLAG1SZ) && !defined(__lint)
220 #define	REPORT_BUFSIZE FLAG1SZ
221 #include "report_bufsize.h"
222 #error "CONV_DYN_FLAG1_BUFSIZE does not match FLAG1SZ"
223 #endif
224 
225 	static const Val_desc vda_def[] = {
226 		{ DF_1_NOW,		MSG_DF_1_NOW_CFNP },
227 		{ DF_1_GLOBAL,		MSG_DF_1_GLOBAL_CFNP },
228 		{ DF_1_GROUP,		MSG_DF_1_GROUP_CFNP },
229 		{ DF_1_NODELETE,	MSG_DF_1_NODELETE_CFNP },
230 		{ DF_1_LOADFLTR,	MSG_DF_1_LOADFLTR_CFNP },
231 		{ DF_1_INITFIRST,	MSG_DF_1_INITFIRST_CFNP },
232 		{ DF_1_NOOPEN,		MSG_DF_1_NOOPEN_CFNP },
233 		{ DF_1_ORIGIN,		MSG_DF_1_ORIGIN_CFNP },
234 		{ DF_1_DIRECT,		MSG_DF_1_DIRECT_CFNP },
235 		{ DF_1_TRANS,		MSG_DF_1_TRANS_CFNP },
236 		{ DF_1_INTERPOSE,	MSG_DF_1_INTERPOSE_DEF },
237 		{ DF_1_NODEFLIB,	MSG_DF_1_NODEFLIB_CFNP },
238 		{ DF_1_NODUMP,		MSG_DF_1_NODUMP_CFNP },
239 		{ DF_1_CONFALT,		MSG_DF_1_CONFALT_CFNP },
240 		{ DF_1_ENDFILTEE,	MSG_DF_1_ENDFILTEE_CFNP },
241 		{ DF_1_DISPRELDNE,	MSG_DF_1_DISPRELDNE_DEF },
242 		{ DF_1_DISPRELPND,	MSG_DF_1_DISPRELPND_DEF },
243 		{ DF_1_NODIRECT,	MSG_DF_1_NODIRECT_CFNP },
244 		{ DF_1_IGNMULDEF,	MSG_DF_1_IGNMULDEF_DEF },
245 		{ DF_1_NOKSYMS,		MSG_DF_1_NOKSYMS_CFNP },
246 		{ DF_1_NOHDR,		MSG_DF_1_NOHDR_CFNP },
247 		{ DF_1_EDITED,		MSG_DF_1_EDITED_CFNP },
248 		{ DF_1_NORELOC,		MSG_DF_1_NORELOC_CFNP },
249 		{ DF_1_SYMINTPOSE,	MSG_DF_1_SYMINTPOSE_DEF },
250 		{ DF_1_GLOBAUDIT,	MSG_DF_1_GLOBAUDIT_DEF },
251 		{ DF_1_SINGLETON,	MSG_DF_1_SINGLETON_DEF },
252 		{ 0,			0 }
253 	};
254 	static const Val_desc vda_cf[] = {
255 		{ DF_1_NOW,		MSG_DF_1_NOW_CF },
256 		{ DF_1_GLOBAL,		MSG_DF_1_GLOBAL_CF },
257 		{ DF_1_GROUP,		MSG_DF_1_GROUP_CF },
258 		{ DF_1_NODELETE,	MSG_DF_1_NODELETE_CF },
259 		{ DF_1_LOADFLTR,	MSG_DF_1_LOADFLTR_CF },
260 		{ DF_1_INITFIRST,	MSG_DF_1_INITFIRST_CF },
261 		{ DF_1_NOOPEN,		MSG_DF_1_NOOPEN_CF },
262 		{ DF_1_ORIGIN,		MSG_DF_1_ORIGIN_CF },
263 		{ DF_1_DIRECT,		MSG_DF_1_DIRECT_CF },
264 		{ DF_1_TRANS,		MSG_DF_1_TRANS_CF },
265 		{ DF_1_INTERPOSE,	MSG_DF_1_INTERPOSE_CF },
266 		{ DF_1_NODEFLIB,	MSG_DF_1_NODEFLIB_CF },
267 		{ DF_1_NODUMP,		MSG_DF_1_NODUMP_CF },
268 		{ DF_1_CONFALT,		MSG_DF_1_CONFALT_CF },
269 		{ DF_1_ENDFILTEE,	MSG_DF_1_ENDFILTEE_CF },
270 		{ DF_1_DISPRELDNE,	MSG_DF_1_DISPRELDNE_CF },
271 		{ DF_1_DISPRELPND,	MSG_DF_1_DISPRELPND_CF },
272 		{ DF_1_NODIRECT,	MSG_DF_1_NODIRECT_CF },
273 		{ DF_1_IGNMULDEF,	MSG_DF_1_IGNMULDEF_CF },
274 		{ DF_1_NOKSYMS,		MSG_DF_1_NOKSYMS_CF },
275 		{ DF_1_NOHDR,		MSG_DF_1_NOHDR_CF },
276 		{ DF_1_EDITED,		MSG_DF_1_EDITED_CF },
277 		{ DF_1_NORELOC,		MSG_DF_1_NORELOC_CF },
278 		{ DF_1_SYMINTPOSE,	MSG_DF_1_SYMINTPOSE_CF },
279 		{ DF_1_GLOBAUDIT,	MSG_DF_1_GLOBAUDIT_CF },
280 		{ DF_1_SINGLETON,	MSG_DF_1_SINGLETON_CF },
281 		{ 0,			0 }
282 	};
283 	static const Val_desc vda_cfnp[] = {
284 		{ DF_1_NOW,		MSG_DF_1_NOW_CFNP },
285 		{ DF_1_GLOBAL,		MSG_DF_1_GLOBAL_CFNP },
286 		{ DF_1_GROUP,		MSG_DF_1_GROUP_CFNP },
287 		{ DF_1_NODELETE,	MSG_DF_1_NODELETE_CFNP },
288 		{ DF_1_LOADFLTR,	MSG_DF_1_LOADFLTR_CFNP },
289 		{ DF_1_INITFIRST,	MSG_DF_1_INITFIRST_CFNP },
290 		{ DF_1_NOOPEN,		MSG_DF_1_NOOPEN_CFNP },
291 		{ DF_1_ORIGIN,		MSG_DF_1_ORIGIN_CFNP },
292 		{ DF_1_DIRECT,		MSG_DF_1_DIRECT_CFNP },
293 		{ DF_1_TRANS,		MSG_DF_1_TRANS_CFNP },
294 		{ DF_1_INTERPOSE,	MSG_DF_1_INTERPOSE_CFNP },
295 		{ DF_1_NODEFLIB,	MSG_DF_1_NODEFLIB_CFNP },
296 		{ DF_1_NODUMP,		MSG_DF_1_NODUMP_CFNP },
297 		{ DF_1_CONFALT,		MSG_DF_1_CONFALT_CFNP },
298 		{ DF_1_ENDFILTEE,	MSG_DF_1_ENDFILTEE_CFNP },
299 		{ DF_1_DISPRELDNE,	MSG_DF_1_DISPRELDNE_CFNP },
300 		{ DF_1_DISPRELPND,	MSG_DF_1_DISPRELPND_CFNP },
301 		{ DF_1_NODIRECT,	MSG_DF_1_NODIRECT_CFNP },
302 		{ DF_1_IGNMULDEF,	MSG_DF_1_IGNMULDEF_CFNP },
303 		{ DF_1_NOKSYMS,		MSG_DF_1_NOKSYMS_CFNP },
304 		{ DF_1_NOHDR,		MSG_DF_1_NOHDR_CFNP },
305 		{ DF_1_EDITED,		MSG_DF_1_EDITED_CFNP },
306 		{ DF_1_NORELOC,		MSG_DF_1_NORELOC_CFNP },
307 		{ DF_1_SYMINTPOSE,	MSG_DF_1_SYMINTPOSE_CFNP },
308 		{ DF_1_GLOBAUDIT,	MSG_DF_1_GLOBAUDIT_CFNP },
309 		{ DF_1_SINGLETON,	MSG_DF_1_SINGLETON_CFNP },
310 		{ 0,			0 }
311 	};
312 	static const Val_desc vda_nf[] = {
313 		{ DF_1_NOW,		MSG_DF_1_NOW_NF },
314 		{ DF_1_GLOBAL,		MSG_DF_1_GLOBAL_NF },
315 		{ DF_1_GROUP,		MSG_DF_1_GROUP_NF },
316 		{ DF_1_NODELETE,	MSG_DF_1_NODELETE_NF },
317 		{ DF_1_LOADFLTR,	MSG_DF_1_LOADFLTR_NF },
318 		{ DF_1_INITFIRST,	MSG_DF_1_INITFIRST_NF },
319 		{ DF_1_NOOPEN,		MSG_DF_1_NOOPEN_NF },
320 		{ DF_1_ORIGIN,		MSG_DF_1_ORIGIN_NF },
321 		{ DF_1_DIRECT,		MSG_DF_1_DIRECT_NF },
322 		{ DF_1_TRANS,		MSG_DF_1_TRANS_NF },
323 		{ DF_1_INTERPOSE,	MSG_DF_1_INTERPOSE_NF },
324 		{ DF_1_NODEFLIB,	MSG_DF_1_NODEFLIB_NF },
325 		{ DF_1_NODUMP,		MSG_DF_1_NODUMP_NF },
326 		{ DF_1_CONFALT,		MSG_DF_1_CONFALT_NF },
327 		{ DF_1_ENDFILTEE,	MSG_DF_1_ENDFILTEE_NF },
328 		{ DF_1_DISPRELDNE,	MSG_DF_1_DISPRELDNE_NF },
329 		{ DF_1_DISPRELPND,	MSG_DF_1_DISPRELPND_NF },
330 		{ DF_1_NODIRECT,	MSG_DF_1_NODIRECT_NF },
331 		{ DF_1_IGNMULDEF,	MSG_DF_1_IGNMULDEF_NF },
332 		{ DF_1_NOKSYMS,		MSG_DF_1_NOKSYMS_NF },
333 		{ DF_1_NOHDR,		MSG_DF_1_NOHDR_NF },
334 		{ DF_1_EDITED,		MSG_DF_1_EDITED_NF },
335 		{ DF_1_NORELOC,		MSG_DF_1_NORELOC_NF },
336 		{ DF_1_SYMINTPOSE,	MSG_DF_1_SYMINTPOSE_NF },
337 		{ DF_1_GLOBAUDIT,	MSG_DF_1_GLOBAUDIT_NF },
338 		{ DF_1_SINGLETON,	MSG_DF_1_SINGLETON_NF },
339 		{ 0,			0 }
340 	};
341 
342 	switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
343 	case CONV_FMT_ALT_CF:
344 		return (vda_cf);
345 	case CONV_FMT_ALT_CFNP:
346 		return (vda_cfnp);
347 	case CONV_FMT_ALT_NF:
348 		return (vda_nf);
349 	}
350 
351 	return (vda_def);
352 }
353 
354 conv_iter_ret_t
355 conv_iter_dyn_flag1(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func,
356     void *uvalue)
357 {
358 	return (conv_iter_vd(conv_dyn_flag1_strings(fmt_flags), func, uvalue));
359 }
360 
361 const Val_desc *
362 conv_dyn_feature1_strings(Conv_fmt_flags_t fmt_flags)
363 {
364 #define	FEATSZ	CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
365 	MSG_DTF_1_PARINIT_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
366 	MSG_DTF_1_CONFEXP_CF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
367 	CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
368 
369 	/*
370 	 * Ensure that Conv_dyn_feature1_buf_t is large enough:
371 	 *
372 	 * FEATSZ is the real min size of the buffer required by
373 	 * conv_dyn_feature1(). However, Conv_dyn_feature1_buf_t uses
374 	 * CONV_DYN_FEATURE1_BUFSIZE to set the buffer size. We do things
375 	 * this way because the definition of FEATSZ uses information that
376 	 * is not available in the environment of other programs that include
377 	 * the conv.h header file.
378 	 */
379 #if (CONV_DYN_FEATURE1_BUFSIZE != FEATSZ) && !defined(__lint)
380 #define	REPORT_BUFSIZE FEATSZ
381 #include "report_bufsize.h"
382 #error "CONV_DYN_FEATURE1_BUFSIZE does not match FEATSZ"
383 #endif
384 
385 	static const Val_desc vda_cf[] = {
386 		{ DTF_1_PARINIT,	MSG_DTF_1_PARINIT_CF },
387 		{ DTF_1_CONFEXP,	MSG_DTF_1_CONFEXP_CF },
388 		{ 0,			0 }
389 	};
390 	static const Val_desc vda_cfnp[] = {
391 		{ DTF_1_PARINIT,	MSG_DTF_1_PARINIT_CFNP },
392 		{ DTF_1_CONFEXP,	MSG_DTF_1_CONFEXP_CFNP },
393 		{ 0,			0 }
394 	};
395 	static const Val_desc vda_nf[] = {
396 		{ DTF_1_PARINIT,	MSG_DTF_1_PARINIT_NF },
397 		{ DTF_1_CONFEXP,	MSG_DTF_1_CONFEXP_NF },
398 		{ 0,			0 }
399 	};
400 
401 	switch (CONV_TYPE_FMT_ALT(fmt_flags)) {
402 	case CONV_FMT_ALT_CF:
403 		return (vda_cf);
404 	case CONV_FMT_ALT_NF:
405 		return (vda_nf);
406 	}
407 
408 	return (vda_cfnp);
409 }
410 
411 conv_iter_ret_t
412 conv_iter_dyn_feature1(Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func,
413     void *uvalue)
414 {
415 	return (conv_iter_vd(conv_dyn_feature1_strings(fmt_flags),
416 	    func, uvalue));
417 }
418 
419 const conv_ds_t **
420 conv_dyn_tag_strings(conv_iter_osabi_t osabi, Half mach,
421     Conv_fmt_flags_t fmt_flags)
422 {
423 	/*
424 	 * Maximum # of items that can be in the returned array. Size this
425 	 * by counting the maximum depth in the switch statement that fills
426 	 * retarr at the end of this function.
427 	 */
428 #define	MAX_RET	12
429 
430 	/*
431 	 * Generic dynamic tags:
432 	 * -	Note hole between DT_FLAGS and DT_PREINIT_ARRAY (tag 32).
433 	 *	We use a 0, which is the signal for "not defined".
434 	 * -	This range has alternative names for dump, requiring an
435 	 *	additional array.
436 	 */
437 	static const Msg	tags_null_cf[] = {
438 		MSG_DT_NULL_CF,			MSG_DT_NEEDED_CF,
439 		MSG_DT_PLTRELSZ_CF,		MSG_DT_PLTGOT_CF,
440 		MSG_DT_HASH_CF,			MSG_DT_STRTAB_CF,
441 		MSG_DT_SYMTAB_CF,		MSG_DT_RELA_CF,
442 		MSG_DT_RELASZ_CF,		MSG_DT_RELAENT_CF,
443 		MSG_DT_STRSZ_CF,		MSG_DT_SYMENT_CF,
444 		MSG_DT_INIT_CF,			MSG_DT_FINI_CF,
445 		MSG_DT_SONAME_CF,		MSG_DT_RPATH_CF,
446 		MSG_DT_SYMBOLIC_CF,		MSG_DT_REL_CF,
447 		MSG_DT_RELSZ_CF,		MSG_DT_RELENT_CF,
448 		MSG_DT_PLTREL_CF,		MSG_DT_DEBUG_CF,
449 		MSG_DT_TEXTREL_CF,		MSG_DT_JMPREL_CF,
450 		MSG_DT_BIND_NOW_CF,		MSG_DT_INIT_ARRAY_CF,
451 		MSG_DT_FINI_ARRAY_CF,		MSG_DT_INIT_ARRAYSZ_CF,
452 		MSG_DT_FINI_ARRAYSZ_CF,		MSG_DT_RUNPATH_CF,
453 		MSG_DT_FLAGS_CF,		0,
454 		MSG_DT_PREINIT_ARRAY_CF,	MSG_DT_PREINIT_ARRAYSZ_CF
455 	};
456 	static const Msg	tags_null_cfnp[] = {
457 		MSG_DT_NULL_CFNP,		MSG_DT_NEEDED_CFNP,
458 		MSG_DT_PLTRELSZ_CFNP,		MSG_DT_PLTGOT_CFNP,
459 		MSG_DT_HASH_CFNP,		MSG_DT_STRTAB_CFNP,
460 		MSG_DT_SYMTAB_CFNP,		MSG_DT_RELA_CFNP,
461 		MSG_DT_RELASZ_CFNP,		MSG_DT_RELAENT_CFNP,
462 		MSG_DT_STRSZ_CFNP,		MSG_DT_SYMENT_CFNP,
463 		MSG_DT_INIT_CFNP,		MSG_DT_FINI_CFNP,
464 		MSG_DT_SONAME_CFNP,		MSG_DT_RPATH_CFNP,
465 		MSG_DT_SYMBOLIC_CFNP,		MSG_DT_REL_CFNP,
466 		MSG_DT_RELSZ_CFNP,		MSG_DT_RELENT_CFNP,
467 		MSG_DT_PLTREL_CFNP,		MSG_DT_DEBUG_CFNP,
468 		MSG_DT_TEXTREL_CFNP,		MSG_DT_JMPREL_CFNP,
469 		MSG_DT_BIND_NOW_CFNP,		MSG_DT_INIT_ARRAY_CFNP,
470 		MSG_DT_FINI_ARRAY_CFNP,		MSG_DT_INIT_ARRAYSZ_CFNP,
471 		MSG_DT_FINI_ARRAYSZ_CFNP,	MSG_DT_RUNPATH_CFNP,
472 		MSG_DT_FLAGS_CFNP,		0,
473 		MSG_DT_PREINIT_ARRAY_CFNP,	MSG_DT_PREINIT_ARRAYSZ_CFNP
474 	};
475 	static const Msg	tags_null_nf[] = {
476 		MSG_DT_NULL_NF,			MSG_DT_NEEDED_NF,
477 		MSG_DT_PLTRELSZ_NF,		MSG_DT_PLTGOT_NF,
478 		MSG_DT_HASH_NF,			MSG_DT_STRTAB_NF,
479 		MSG_DT_SYMTAB_NF,		MSG_DT_RELA_NF,
480 		MSG_DT_RELASZ_NF,		MSG_DT_RELAENT_NF,
481 		MSG_DT_STRSZ_NF,		MSG_DT_SYMENT_NF,
482 		MSG_DT_INIT_NF,			MSG_DT_FINI_NF,
483 		MSG_DT_SONAME_NF,		MSG_DT_RPATH_NF,
484 		MSG_DT_SYMBOLIC_NF,		MSG_DT_REL_NF,
485 		MSG_DT_RELSZ_NF,		MSG_DT_RELENT_NF,
486 		MSG_DT_PLTREL_NF,		MSG_DT_DEBUG_NF,
487 		MSG_DT_TEXTREL_NF,		MSG_DT_JMPREL_NF,
488 		MSG_DT_BIND_NOW_NF,		MSG_DT_INIT_ARRAY_NF,
489 		MSG_DT_FINI_ARRAY_NF,		MSG_DT_INIT_ARRAYSZ_NF,
490 		MSG_DT_FINI_ARRAYSZ_NF,		MSG_DT_RUNPATH_NF,
491 		MSG_DT_FLAGS_NF,		0,
492 		MSG_DT_PREINIT_ARRAY_NF,	MSG_DT_PREINIT_ARRAYSZ_NF
493 	};
494 	static const Msg	tags_null_dmp[] = {
495 		MSG_DT_NULL_CFNP,		MSG_DT_NEEDED_CFNP,
496 		MSG_DT_PLTRELSZ_DMP,		MSG_DT_PLTGOT_CFNP,
497 		MSG_DT_HASH_CFNP,		MSG_DT_STRTAB_CFNP,
498 		MSG_DT_SYMTAB_CFNP,		MSG_DT_RELA_CFNP,
499 		MSG_DT_RELASZ_CFNP,		MSG_DT_RELAENT_CFNP,
500 		MSG_DT_STRSZ_CFNP,		MSG_DT_SYMENT_CFNP,
501 		MSG_DT_INIT_CFNP,		MSG_DT_FINI_CFNP,
502 		MSG_DT_SONAME_CFNP,		MSG_DT_RPATH_CFNP,
503 		MSG_DT_SYMBOLIC_DMP,		MSG_DT_REL_CFNP,
504 		MSG_DT_RELSZ_CFNP,		MSG_DT_RELENT_CFNP,
505 		MSG_DT_PLTREL_CFNP,		MSG_DT_DEBUG_CFNP,
506 		MSG_DT_TEXTREL_CFNP,		MSG_DT_JMPREL_CFNP,
507 		MSG_DT_BIND_NOW_CFNP,		MSG_DT_INIT_ARRAY_CFNP,
508 		MSG_DT_FINI_ARRAY_CFNP,		MSG_DT_INIT_ARRAYSZ_CFNP,
509 		MSG_DT_FINI_ARRAYSZ_CFNP,	MSG_DT_RUNPATH_CFNP,
510 		MSG_DT_FLAGS_CFNP,		0,
511 		MSG_DT_PREINIT_ARRAY_CFNP,	MSG_DT_PREINIT_ARRAYSZ_CFNP
512 	};
513 	static const conv_ds_msg_t ds_null_cf = {
514 	    CONV_DS_MSG_INIT(DT_NULL, tags_null_cf) };
515 	static const conv_ds_msg_t ds_null_cfnp = {
516 	    CONV_DS_MSG_INIT(DT_NULL, tags_null_cfnp) };
517 	static const conv_ds_msg_t ds_null_nf = {
518 	    CONV_DS_MSG_INIT(DT_NULL, tags_null_nf) };
519 	static const conv_ds_msg_t ds_null_dmp = {
520 	    CONV_DS_MSG_INIT(DT_NULL, tags_null_dmp) };
521 
522 	/*
523 	 * DT_SPARC_REGISTER was originally assigned 0x7000001. It is processor
524 	 * specific, and should have been in the range DT_LOPROC-DT_HIPROC
525 	 * instead of here. When the error was fixed,
526 	 * DT_DEPRECATED_SPARC_REGISTER was created to maintain backward
527 	 * compatability.
528 	 */
529 	static const Msg	tags_sdreg_cf[] = {
530 	    MSG_DT_DEP_SPARC_REG_CF };
531 	static const Msg	tags_sdreg_cfnp[] = {
532 	    MSG_DT_DEP_SPARC_REG_CFNP };
533 	static const Msg	tags_sdreg_nf[] = {
534 	    MSG_DT_DEP_SPARC_REG_NF };
535 
536 	static const conv_ds_msg_t ds_sdreg_cf = {
537 	    CONV_DS_MSG_INIT(DT_DEPRECATED_SPARC_REGISTER, tags_sdreg_cf) };
538 	static const conv_ds_msg_t ds_sdreg_cfnp = {
539 	    CONV_DS_MSG_INIT(DT_DEPRECATED_SPARC_REGISTER, tags_sdreg_cfnp) };
540 	static const conv_ds_msg_t ds_sdreg_nf = {
541 	    CONV_DS_MSG_INIT(DT_DEPRECATED_SPARC_REGISTER, tags_sdreg_nf) };
542 
543 
544 	/*
545 	 * SUNW: DT_LOOS -> DT_HIOS range. Note holes between DT_SUNW_TLSSORTSZ,
546 	 * DT_SUNW_STRPAD, and DT_SUNW_LDMACH. We handle the outliers
547 	 * separately below as single values.
548 	 */
549 	static const Msg	tags_sunw_auxiliary_cf[] = {
550 		MSG_DT_SUNW_AUXILIARY_CF,	MSG_DT_SUNW_RTLDINF_CF,
551 		MSG_DT_SUNW_FILTER_CF,		MSG_DT_SUNW_CAP_CF,
552 		MSG_DT_SUNW_SYMTAB_CF,		MSG_DT_SUNW_SYMSZ_CF,
553 		MSG_DT_SUNW_SORTENT_CF,		MSG_DT_SUNW_SYMSORT_CF,
554 		MSG_DT_SUNW_SYMSORTSZ_CF,	MSG_DT_SUNW_TLSSORT_CF,
555 		MSG_DT_SUNW_TLSSORTSZ_CF,	MSG_DT_SUNW_CAPINFO_CF,
556 		MSG_DT_SUNW_STRPAD_CF,		MSG_DT_SUNW_CAPCHAIN_CF,
557 		MSG_DT_SUNW_LDMACH_CF,		0,
558 		MSG_DT_SUNW_CAPCHAINENT_CF,	0,
559 		MSG_DT_SUNW_CAPCHAINSZ_CF,	0,
560 		0,				0,
561 		MSG_DT_SUNW_ASLR_CF,		0,
562 		0,				0,
563 		MSG_DT_SUNW_KMOD_CF
564 	};
565 	static const Msg	tags_sunw_auxiliary_cfnp[] = {
566 		MSG_DT_SUNW_AUXILIARY_CFNP,	MSG_DT_SUNW_RTLDINF_CFNP,
567 		MSG_DT_SUNW_FILTER_CFNP,	MSG_DT_SUNW_CAP_CFNP,
568 		MSG_DT_SUNW_SYMTAB_CFNP,	MSG_DT_SUNW_SYMSZ_CFNP,
569 		MSG_DT_SUNW_SORTENT_CFNP,	MSG_DT_SUNW_SYMSORT_CFNP,
570 		MSG_DT_SUNW_SYMSORTSZ_CFNP,	MSG_DT_SUNW_TLSSORT_CFNP,
571 		MSG_DT_SUNW_TLSSORTSZ_CFNP,	MSG_DT_SUNW_CAPINFO_CFNP,
572 		MSG_DT_SUNW_STRPAD_CFNP,	MSG_DT_SUNW_CAPCHAIN_CFNP,
573 		MSG_DT_SUNW_LDMACH_CFNP,	0,
574 		MSG_DT_SUNW_CAPCHAINENT_CFNP,	0,
575 		MSG_DT_SUNW_CAPCHAINSZ_CFNP,	0,
576 		0,				0,
577 		MSG_DT_SUNW_ASLR_CFNP,		0,
578 		0,				0,
579 		MSG_DT_SUNW_KMOD_CFNP
580 	};
581 	static const Msg	tags_sunw_auxiliary_nf[] = {
582 		MSG_DT_SUNW_AUXILIARY_NF,	MSG_DT_SUNW_RTLDINF_NF,
583 		MSG_DT_SUNW_FILTER_NF,		MSG_DT_SUNW_CAP_NF,
584 		MSG_DT_SUNW_SYMTAB_NF,		MSG_DT_SUNW_SYMSZ_NF,
585 		MSG_DT_SUNW_SORTENT_NF,		MSG_DT_SUNW_SYMSORT_NF,
586 		MSG_DT_SUNW_SYMSORTSZ_NF,	MSG_DT_SUNW_TLSSORT_NF,
587 		MSG_DT_SUNW_TLSSORTSZ_NF,	MSG_DT_SUNW_CAPINFO_NF,
588 		MSG_DT_SUNW_STRPAD_NF,		MSG_DT_SUNW_CAPCHAIN_NF,
589 		MSG_DT_SUNW_LDMACH_NF,		0,
590 		MSG_DT_SUNW_CAPCHAINENT_NF,	0,
591 		MSG_DT_SUNW_CAPCHAINSZ_NF,	0,
592 		0,				0,
593 		MSG_DT_SUNW_ASLR_NF,		0,
594 		0,				0,
595 		MSG_DT_SUNW_KMOD_NF
596 	};
597 	static const conv_ds_msg_t ds_sunw_auxiliary_cf = {
598 	    CONV_DS_MSG_INIT(DT_SUNW_AUXILIARY, tags_sunw_auxiliary_cf) };
599 	static const conv_ds_msg_t ds_sunw_auxiliary_cfnp = {
600 	    CONV_DS_MSG_INIT(DT_SUNW_AUXILIARY, tags_sunw_auxiliary_cfnp) };
601 	static const conv_ds_msg_t ds_sunw_auxiliary_nf = {
602 	    CONV_DS_MSG_INIT(DT_SUNW_AUXILIARY, tags_sunw_auxiliary_nf) };
603 
604 	/*
605 	 * GNU: (In DT_VALRNGLO section) DT_GNU_PRELINKED - DT_GNU_LIBLISTSZ
606 	 */
607 	static const Msg	tags_gnu_prelinked_cf[] = {
608 		MSG_DT_GNU_PRELINKED_CF,	MSG_DT_GNU_CONFLICTSZ_CF,
609 		MSG_DT_GNU_LIBLISTSZ_CF
610 	};
611 	static const Msg	tags_gnu_prelinked_cfnp[] = {
612 		MSG_DT_GNU_PRELINKED_CFNP,	MSG_DT_GNU_CONFLICTSZ_CFNP,
613 		MSG_DT_GNU_LIBLISTSZ_CFNP
614 	};
615 	static const Msg	tags_gnu_prelinked_nf[] = {
616 		MSG_DT_GNU_PRELINKED_NF,	MSG_DT_GNU_CONFLICTSZ_NF,
617 		MSG_DT_GNU_LIBLISTSZ_NF
618 	};
619 	static const conv_ds_msg_t ds_gnu_prelinked_cf = {
620 	    CONV_DS_MSG_INIT(DT_GNU_PRELINKED, tags_gnu_prelinked_cf) };
621 	static const conv_ds_msg_t ds_gnu_prelinked_cfnp = {
622 	    CONV_DS_MSG_INIT(DT_GNU_PRELINKED, tags_gnu_prelinked_cfnp) };
623 	static const conv_ds_msg_t ds_gnu_prelinked_nf = {
624 	    CONV_DS_MSG_INIT(DT_GNU_PRELINKED, tags_gnu_prelinked_nf) };
625 
626 	/*
627 	 * SUNW: DT_VALRNGLO - DT_VALRNGHI range.
628 	 */
629 	static const Msg	tags_checksum_cf[] = {
630 		MSG_DT_CHECKSUM_CF,		MSG_DT_PLTPADSZ_CF,
631 		MSG_DT_MOVEENT_CF,		MSG_DT_MOVESZ_CF,
632 		MSG_DT_FEATURE_1_CF,		MSG_DT_POSFLAG_1_CF,
633 		MSG_DT_SYMINSZ_CF,		MSG_DT_SYMINENT_CF
634 	};
635 	static const Msg	tags_checksum_cfnp[] = {
636 		MSG_DT_CHECKSUM_CFNP,		MSG_DT_PLTPADSZ_CFNP,
637 		MSG_DT_MOVEENT_CFNP,		MSG_DT_MOVESZ_CFNP,
638 		MSG_DT_FEATURE_1_CFNP,		MSG_DT_POSFLAG_1_CFNP,
639 		MSG_DT_SYMINSZ_CFNP,		MSG_DT_SYMINENT_CFNP
640 	};
641 	static const Msg	tags_checksum_nf[] = {
642 		MSG_DT_CHECKSUM_NF,		MSG_DT_PLTPADSZ_NF,
643 		MSG_DT_MOVEENT_NF,		MSG_DT_MOVESZ_NF,
644 		MSG_DT_FEATURE_1_NF,		MSG_DT_POSFLAG_1_NF,
645 		MSG_DT_SYMINSZ_NF,		MSG_DT_SYMINENT_NF
646 	};
647 	static const conv_ds_msg_t ds_checksum_cf = {
648 	    CONV_DS_MSG_INIT(DT_CHECKSUM, tags_checksum_cf) };
649 	static const conv_ds_msg_t ds_checksum_cfnp = {
650 	    CONV_DS_MSG_INIT(DT_CHECKSUM, tags_checksum_cfnp) };
651 	static const conv_ds_msg_t ds_checksum_nf = {
652 	    CONV_DS_MSG_INIT(DT_CHECKSUM, tags_checksum_nf) };
653 
654 	/*
655 	 * GNU: (In DT_ADDRRNGLO section) DT_GNU_HASH - DT_GNU_LIBLIST
656 	 */
657 	static const Msg	tags_gnu_hash_cf[] = {
658 		MSG_DT_GNU_HASH_CF,		MSG_DT_TLSDESC_PLT_CF,
659 		MSG_DT_TLSDESC_GOT_CF,		MSG_DT_GNU_CONFLICT_CF,
660 		MSG_DT_GNU_LIBLIST_CF
661 	};
662 	static const Msg	tags_gnu_hash_cfnp[] = {
663 		MSG_DT_GNU_HASH_CFNP,		MSG_DT_TLSDESC_PLT_CFNP,
664 		MSG_DT_TLSDESC_GOT_CFNP,	MSG_DT_GNU_CONFLICT_CFNP,
665 		MSG_DT_GNU_LIBLIST_CFNP
666 	};
667 	static const Msg	tags_gnu_hash_nf[] = {
668 		MSG_DT_GNU_HASH_NF,		MSG_DT_TLSDESC_PLT_NF,
669 		MSG_DT_TLSDESC_GOT_NF,		MSG_DT_GNU_CONFLICT_NF,
670 		MSG_DT_GNU_LIBLIST_NF
671 	};
672 	static const conv_ds_msg_t ds_gnu_hash_cf = {
673 	    CONV_DS_MSG_INIT(DT_GNU_HASH, tags_gnu_hash_cf) };
674 	static const conv_ds_msg_t ds_gnu_hash_cfnp = {
675 	    CONV_DS_MSG_INIT(DT_GNU_HASH, tags_gnu_hash_cfnp) };
676 	static const conv_ds_msg_t ds_gnu_hash_nf = {
677 	    CONV_DS_MSG_INIT(DT_GNU_HASH, tags_gnu_hash_nf) };
678 
679 	/*
680 	 * SUNW: DT_ADDRRNGLO - DT_ADDRRNGHI range.
681 	 */
682 	static const Msg	tags_config_cf[] = {
683 		MSG_DT_CONFIG_CF,		MSG_DT_DEPAUDIT_CF,
684 		MSG_DT_AUDIT_CF,		MSG_DT_PLTPAD_CF,
685 		MSG_DT_MOVETAB_CF,		MSG_DT_SYMINFO_CF
686 	};
687 	static const Msg	tags_config_cfnp[] = {
688 		MSG_DT_CONFIG_CFNP,		MSG_DT_DEPAUDIT_CFNP,
689 		MSG_DT_AUDIT_CFNP,		MSG_DT_PLTPAD_CFNP,
690 		MSG_DT_MOVETAB_CFNP,		MSG_DT_SYMINFO_CFNP
691 	};
692 	static const Msg	tags_config_nf[] = {
693 		MSG_DT_CONFIG_NF,		MSG_DT_DEPAUDIT_NF,
694 		MSG_DT_AUDIT_NF,		MSG_DT_PLTPAD_NF,
695 		MSG_DT_MOVETAB_NF,		MSG_DT_SYMINFO_NF
696 	};
697 	static const conv_ds_msg_t ds_config_cf = {
698 	    CONV_DS_MSG_INIT(DT_CONFIG, tags_config_cf) };
699 	static const conv_ds_msg_t ds_config_cfnp = {
700 	    CONV_DS_MSG_INIT(DT_CONFIG, tags_config_cfnp) };
701 	static const conv_ds_msg_t ds_config_nf = {
702 	    CONV_DS_MSG_INIT(DT_CONFIG, tags_config_nf) };
703 
704 	/*
705 	 * SUNW: generic range. Note hole between DT_VERSYM and DT_RELACOUNT.
706 	 */
707 	static const Msg	tags_versym_cf[] = { MSG_DT_VERSYM_CF };
708 	static const Msg	tags_versym_cfnp[] = { MSG_DT_VERSYM_CFNP };
709 	static const Msg	tags_versym_nf[] = { MSG_DT_VERSYM_NF };
710 	static const conv_ds_msg_t ds_versym_cf = {
711 	    CONV_DS_MSG_INIT(DT_VERSYM, tags_versym_cf) };
712 	static const conv_ds_msg_t ds_versym_cfnp = {
713 	    CONV_DS_MSG_INIT(DT_VERSYM, tags_versym_cfnp) };
714 	static const conv_ds_msg_t ds_versym_nf = {
715 	    CONV_DS_MSG_INIT(DT_VERSYM, tags_versym_nf) };
716 
717 	static const Msg	tags_relacount_cf[] = {
718 		MSG_DT_RELACOUNT_CF,		MSG_DT_RELCOUNT_CF,
719 		MSG_DT_FLAGS_1_CF,		MSG_DT_VERDEF_CF,
720 		MSG_DT_VERDEFNUM_CF,		MSG_DT_VERNEED_CF,
721 		MSG_DT_VERNEEDNUM_CF
722 	};
723 	static const Msg	tags_relacount_cfnp[] = {
724 		MSG_DT_RELACOUNT_CFNP,		MSG_DT_RELCOUNT_CFNP,
725 		MSG_DT_FLAGS_1_CFNP,		MSG_DT_VERDEF_CFNP,
726 		MSG_DT_VERDEFNUM_CFNP,		MSG_DT_VERNEED_CFNP,
727 		MSG_DT_VERNEEDNUM_CFNP
728 	};
729 	static const Msg	tags_relacount_nf[] = {
730 		MSG_DT_RELACOUNT_NF,		MSG_DT_RELCOUNT_NF,
731 		MSG_DT_FLAGS_1_NF,		MSG_DT_VERDEF_NF,
732 		MSG_DT_VERDEFNUM_NF,		MSG_DT_VERNEED_NF,
733 		MSG_DT_VERNEEDNUM_NF
734 	};
735 	static const conv_ds_msg_t ds_relacount_cf = {
736 	    CONV_DS_MSG_INIT(DT_RELACOUNT, tags_relacount_cf) };
737 	static const conv_ds_msg_t ds_relacount_cfnp = {
738 	    CONV_DS_MSG_INIT(DT_RELACOUNT, tags_relacount_cfnp) };
739 	static const conv_ds_msg_t ds_relacount_nf = {
740 	    CONV_DS_MSG_INIT(DT_RELACOUNT, tags_relacount_nf) };
741 
742 	/*
743 	 * DT_LOPROC - DT_HIPROC range: solaris/sparc-only
744 	 */
745 	static const Msg tags_sparc_reg_cf[] = { MSG_DT_SPARC_REGISTER_CF };
746 	static const Msg tags_sparc_reg_cfnp[] = { MSG_DT_SPARC_REGISTER_CFNP };
747 	static const Msg tags_sparc_reg_nf[] = { MSG_DT_SPARC_REGISTER_NF };
748 	static const Msg tags_sparc_reg_dmp[] = { MSG_DT_SPARC_REGISTER_DMP };
749 	static const conv_ds_msg_t ds_sparc_reg_cf = {
750 	    CONV_DS_MSG_INIT(DT_SPARC_REGISTER, tags_sparc_reg_cf) };
751 	static const conv_ds_msg_t ds_sparc_reg_cfnp = {
752 	    CONV_DS_MSG_INIT(DT_SPARC_REGISTER, tags_sparc_reg_cfnp) };
753 	static const conv_ds_msg_t ds_sparc_reg_nf = {
754 	    CONV_DS_MSG_INIT(DT_SPARC_REGISTER, tags_sparc_reg_nf) };
755 	static const conv_ds_msg_t ds_sparc_reg_dmp = {
756 	    CONV_DS_MSG_INIT(DT_SPARC_REGISTER, tags_sparc_reg_dmp) };
757 
758 	/*
759 	 * DT_LOPROC - DT_HIPROC range: Solaris osabi, all hardware
760 	 */
761 	static const Msg	tags_auxiliary_cf[] = {
762 		MSG_DT_AUXILIARY_CF,	MSG_DT_USED_CF,
763 		MSG_DT_FILTER_CF
764 	};
765 	static const Msg	tags_auxiliary_cfnp[] = {
766 		MSG_DT_AUXILIARY_CFNP,	MSG_DT_USED_CFNP,
767 		MSG_DT_FILTER_CFNP
768 	};
769 	static const Msg	tags_auxiliary_nf[] = {
770 		MSG_DT_AUXILIARY_NF,	MSG_DT_USED_NF,
771 		MSG_DT_FILTER_NF
772 	};
773 	static const conv_ds_msg_t ds_auxiliary_cf = {
774 	    CONV_DS_MSG_INIT(DT_AUXILIARY, tags_auxiliary_cf) };
775 	static const conv_ds_msg_t ds_auxiliary_cfnp = {
776 	    CONV_DS_MSG_INIT(DT_AUXILIARY, tags_auxiliary_cfnp) };
777 	static const conv_ds_msg_t ds_auxiliary_nf = {
778 	    CONV_DS_MSG_INIT(DT_AUXILIARY, tags_auxiliary_nf) };
779 
780 
781 	static const conv_ds_t	*retarr[MAX_RET];
782 
783 	int	ndx = 0;
784 	int	fmt_osabi = CONV_TYPE_FMT_ALT(fmt_flags);
785 	int	mach_sparc, osabi_solaris, osabi_linux;
786 
787 
788 
789 	osabi_solaris = (osabi == ELFOSABI_NONE) ||
790 	    (osabi == ELFOSABI_SOLARIS) || (osabi == CONV_OSABI_ALL);
791 	osabi_linux = (osabi == ELFOSABI_LINUX) || (osabi == CONV_OSABI_ALL);
792 	mach_sparc = (mach == EM_SPARC) || (mach == EM_SPARCV9) ||
793 	    (mach == EM_SPARC32PLUS) || (mach == CONV_MACH_ALL);
794 
795 	/*
796 	 * Fill in retarr with the descriptors for the messages that
797 	 * apply to the current osabi. Note that we order these items such
798 	 * that the more common are placed at the beginning, and the less
799 	 * likely at the end. This should speed the common case.
800 	 *
801 	 * Note that the CFNP and DMP styles are very similar, so they
802 	 * are combined in 'default', and fmt_osabi is consulted when there
803 	 * are differences.
804 	 */
805 	switch (fmt_osabi) {
806 	case CONV_FMT_ALT_CF:
807 		retarr[ndx++] = CONV_DS_ADDR(ds_null_cf);
808 		if (osabi_solaris)
809 			retarr[ndx++] = CONV_DS_ADDR(ds_sunw_auxiliary_cf);
810 		retarr[ndx++] = CONV_DS_ADDR(ds_checksum_cf);
811 		retarr[ndx++] = CONV_DS_ADDR(ds_config_cf);
812 		retarr[ndx++] = CONV_DS_ADDR(ds_versym_cf);
813 		retarr[ndx++] = CONV_DS_ADDR(ds_relacount_cf);
814 		if (osabi_solaris) {
815 			retarr[ndx++] = CONV_DS_ADDR(ds_auxiliary_cf);
816 			if (mach_sparc) {
817 				retarr[ndx++] = CONV_DS_ADDR(ds_sparc_reg_cf);
818 				retarr[ndx++] = CONV_DS_ADDR(ds_sdreg_cf);
819 			}
820 		}
821 		if (osabi_linux) {
822 			retarr[ndx++] = CONV_DS_ADDR(ds_gnu_prelinked_cf);
823 			retarr[ndx++] = CONV_DS_ADDR(ds_gnu_hash_cf);
824 		}
825 		break;
826 
827 	case CONV_FMT_ALT_NF:
828 		retarr[ndx++] = CONV_DS_ADDR(ds_null_nf);
829 		if (osabi_solaris)
830 			retarr[ndx++] = CONV_DS_ADDR(ds_sunw_auxiliary_nf);
831 		retarr[ndx++] = CONV_DS_ADDR(ds_checksum_nf);
832 		retarr[ndx++] = CONV_DS_ADDR(ds_config_nf);
833 		retarr[ndx++] = CONV_DS_ADDR(ds_versym_nf);
834 		retarr[ndx++] = CONV_DS_ADDR(ds_relacount_nf);
835 		if (osabi_solaris) {
836 			retarr[ndx++] = CONV_DS_ADDR(ds_auxiliary_nf);
837 			if (mach_sparc) {
838 				retarr[ndx++] = CONV_DS_ADDR(ds_sparc_reg_nf);
839 				retarr[ndx++] = CONV_DS_ADDR(ds_sdreg_nf);
840 			}
841 		}
842 		if (osabi_linux) {
843 			retarr[ndx++] = CONV_DS_ADDR(ds_gnu_prelinked_nf);
844 			retarr[ndx++] = CONV_DS_ADDR(ds_gnu_hash_nf);
845 		}
846 		break;
847 	default:
848 		/*
849 		 * The default style for the generic range is CFNP,
850 		 * while dump has a couple of different strings.
851 		 */
852 
853 		retarr[ndx++] = (fmt_osabi == CONV_FMT_ALT_DUMP) ?
854 		    CONV_DS_ADDR(ds_null_dmp) : CONV_DS_ADDR(ds_null_cfnp);
855 		if (osabi_solaris)
856 			retarr[ndx++] = CONV_DS_ADDR(ds_sunw_auxiliary_cfnp);
857 		retarr[ndx++] = CONV_DS_ADDR(ds_checksum_cfnp);
858 		retarr[ndx++] = CONV_DS_ADDR(ds_config_cfnp);
859 		retarr[ndx++] = CONV_DS_ADDR(ds_versym_cfnp);
860 		retarr[ndx++] = CONV_DS_ADDR(ds_relacount_cfnp);
861 		if (osabi_solaris) {
862 			retarr[ndx++] = CONV_DS_ADDR(ds_auxiliary_cfnp);
863 			if (mach_sparc) {
864 				/*
865 				 * The default style for DT_SPARC_REGISTER
866 				 * is the dump style, which omits the 'SPARC_'.
867 				 * CFNP keeps the prefix.
868 				 */
869 				retarr[ndx++] =
870 				    (fmt_osabi == CONV_FMT_ALT_CFNP) ?
871 				    CONV_DS_ADDR(ds_sparc_reg_cfnp) :
872 				    CONV_DS_ADDR(ds_sparc_reg_dmp);
873 				retarr[ndx++] = CONV_DS_ADDR(ds_sdreg_cfnp);
874 			}
875 		}
876 		if (osabi_linux) {
877 			retarr[ndx++] = CONV_DS_ADDR(ds_gnu_prelinked_cfnp);
878 			retarr[ndx++] = CONV_DS_ADDR(ds_gnu_hash_cfnp);
879 		}
880 		break;
881 	}
882 
883 	retarr[ndx++] = NULL;
884 	assert(ndx <= MAX_RET);
885 	return (retarr);
886 }
887 
888 conv_iter_ret_t
889 conv_iter_dyn_tag(conv_iter_osabi_t osabi, Half mach,
890     Conv_fmt_flags_t fmt_flags, conv_iter_cb_t func, void *uvalue)
891 {
892 	return (conv_iter_ds(osabi, mach,
893 	    conv_dyn_tag_strings(osabi, mach, fmt_flags), func, uvalue));
894 }
895 
896 
897 #define	BINDTSZ	CONV_EXPN_FIELD_DEF_PREFIX_SIZE +			\
898 		MSG_BND_NEEDED_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
899 		MSG_BND_REFER_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
900 		MSG_BND_FILTER_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
901 		CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
902 
903 /*
904  * Ensure that Conv_bnd_type_buf_t is large enough:
905  *
906  * BINDTSZ is the real minimum size of the buffer required by conv_bnd_type().
907  * However, Conv_bnd_type_buf_t uses CONV_BND_TYPE_BUFSIZE to set the
908  * buffer size. We do things this way because the definition of BINDTSZ uses
909  * information that is not available in the environment of other programs
910  * that include the conv.h header file.
911  */
912 #if (CONV_BND_TYPE_BUFSIZE != BINDTSZ) && !defined(__lint)
913 #define	REPORT_BUFSIZE BINDTSZ
914 #include "report_bufsize.h"
915 #error "CONV_BND_TYPE_BUFSIZE does not match BINDTSZ"
916 #endif
917 
918 const char *
919 conv_bnd_type(uint_t flags, Conv_bnd_type_buf_t *bnd_type_buf)
920 {
921 	static const Val_desc vda[] = {
922 		{ BND_NEEDED,		MSG_BND_NEEDED },
923 		{ BND_REFER,		MSG_BND_REFER },
924 		{ BND_FILTER,		MSG_BND_FILTER },
925 		{ 0,			0 }
926 	};
927 	static CONV_EXPN_FIELD_ARG conv_arg = {
928 	    NULL, sizeof (bnd_type_buf->buf) };
929 
930 	if (flags == 0)
931 		return (MSG_ORIG(MSG_STR_EMPTY));
932 
933 	conv_arg.buf = bnd_type_buf->buf;
934 	conv_arg.oflags = conv_arg.rflags = flags;
935 	(void) conv_expn_field(&conv_arg, vda, 0);
936 
937 	return ((const char *)bnd_type_buf->buf);
938 }
939 
940 /*
941  * Note, conv_bnd_obj() is called with either:
942  *	LML_FLG_OBJADDED (possibly with LML_FLG_OBJREEVAL added), or
943  *	LML_FLG_OBJDELETED, or
944  *	LML_FLG_ATEXIT.
945  */
946 #define	BINDOSZ	CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
947 		MSG_BND_ADDED_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
948 		MSG_BND_REEVAL_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
949 		CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
950 
951 /*
952  * Ensure that Conv_bnd_obj_buf_t is large enough:
953  *
954  * BINDOSZ is the real minimum size of the buffer required by conv_bnd_obj().
955  * However, Conv_bnd_obj_buf_t uses CONV_BND_OBJ_BUFSIZE to set the
956  * buffer size. We do things this way because the definition of BINDOSZ uses
957  * information that is not available in the environment of other programs
958  * that include the conv.h header file.
959  */
960 #if (CONV_BND_OBJ_BUFSIZE != BINDOSZ) && !defined(__lint)
961 #define	REPORT_BUFSIZE BINDOSZ
962 #include "report_bufsize.h"
963 #error "CONV_BND_OBJ_BUFSIZE does not match BINDOSZ"
964 #endif
965 
966 const char *
967 conv_bnd_obj(uint_t flags, Conv_bnd_obj_buf_t *bnd_obj_buf)
968 {
969 	static const Val_desc vda[] = {
970 		{ LML_FLG_OBJADDED,	MSG_BND_ADDED },
971 		{ LML_FLG_OBJREEVAL,	MSG_BND_REEVAL },
972 		{ LML_FLG_OBJDELETED,	MSG_BND_DELETED },
973 		{ LML_FLG_ATEXIT,	MSG_BND_ATEXIT },
974 		{ 0,			0 }
975 	};
976 	static CONV_EXPN_FIELD_ARG conv_arg = {
977 	    NULL, sizeof (bnd_obj_buf->buf) };
978 
979 	if ((flags & (LML_FLG_OBJADDED | LML_FLG_OBJREEVAL |
980 	    LML_FLG_OBJDELETED | LML_FLG_ATEXIT)) == 0)
981 		return (MSG_ORIG(MSG_BND_REVISIT));
982 
983 	/*
984 	 * Note, we're not worried about unknown flags for this family, only
985 	 * the selected flags are of interest, so we leave conv_arg.rflags
986 	 * set to 0.
987 	 */
988 	conv_arg.buf = bnd_obj_buf->buf;
989 	conv_arg.oflags = flags;
990 	(void) conv_expn_field(&conv_arg, vda, 0);
991 
992 	return ((const char *)bnd_obj_buf->buf);
993 }
994