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