dynamic.c revision 1698:0cf90a9f4e74
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 2006 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26#pragma ident	"%Z%%M%	%I%	%E% SMI"
27
28/*
29 * String conversion routine for .dynamic tag entries.
30 */
31#include	<stdio.h>
32#include	<string.h>
33#include	<sys/elf_SPARC.h>
34#include	"rtld.h"
35#include	"_conv.h"
36#include	"dynamic_msg.h"
37
38#define	POSSZ	MSG_GBL_OSQBRKT_SIZE + \
39		MSG_DFP_LAZYLOAD_SIZE + \
40		MSG_DFP_GROUPPERM_SIZE + \
41		CONV_INV_STRSIZE + MSG_GBL_CSQBRKT_SIZE
42
43const char *
44conv_dyn_posflag1(Xword flags)
45{
46	static char	string[POSSZ];
47	static Val_desc vda[] = {
48		{ DF_P1_LAZYLOAD,	MSG_ORIG(MSG_DFP_LAZYLOAD) },
49		{ DF_P1_GROUPPERM,	MSG_ORIG(MSG_DFP_GROUPPERM) },
50		{ 0,			0 }
51	};
52
53	if (flags == 0)
54		return (MSG_ORIG(MSG_GBL_ZERO));
55
56	(void) strlcpy(string, MSG_ORIG(MSG_GBL_OSQBRKT), POSSZ);
57	if (conv_expn_field(string, POSSZ, vda, flags, flags, 0, 0))
58		(void) strlcat(string, MSG_ORIG(MSG_GBL_CSQBRKT), POSSZ);
59
60	return ((const char *)string);
61}
62
63#define	FLAGSZ	MSG_GBL_OSQBRKT_SIZE + \
64		MSG_DF_ORIGIN_SIZE + \
65		MSG_DF_SYMBOLIC_SIZE + \
66		MSG_DF_TEXTREL_SIZE + \
67		MSG_DF_BIND_NOW_SIZE + \
68		MSG_DF_STATIC_TLS_SIZE + \
69		CONV_INV_STRSIZE + MSG_GBL_CSQBRKT_SIZE
70
71const char *
72conv_dyn_flag(Xword flags)
73{
74	static char	string[FLAGSZ];
75	static Val_desc vda[] = {
76		{ DF_ORIGIN,		MSG_ORIG(MSG_DF_ORIGIN) },
77		{ DF_SYMBOLIC,		MSG_ORIG(MSG_DF_SYMBOLIC) },
78		{ DF_TEXTREL,		MSG_ORIG(MSG_DF_TEXTREL) },
79		{ DF_BIND_NOW,		MSG_ORIG(MSG_DF_BIND_NOW) },
80		{ DF_STATIC_TLS,	MSG_ORIG(MSG_DF_STATIC_TLS) },
81		{ 0,			0 }
82	};
83
84	if (flags == 0)
85		return (MSG_ORIG(MSG_GBL_ZERO));
86
87	(void) strlcpy(string, MSG_ORIG(MSG_GBL_OSQBRKT), FLAGSZ);
88	if (conv_expn_field(string, FLAGSZ, vda, flags, flags, 0, 0))
89		(void) strlcat(string, MSG_ORIG(MSG_GBL_CSQBRKT), FLAGSZ);
90
91	return ((const char *)string);
92}
93
94#define	FLAG1SZ	MSG_GBL_OSQBRKT_SIZE + \
95		MSG_DF1_NOW_SIZE + \
96		MSG_DF1_GLOBAL_SIZE + \
97		MSG_DF1_GROUP_SIZE + \
98		MSG_DF1_NODELETE_SIZE + \
99		MSG_DF1_LOADFLTR_SIZE + \
100		MSG_DF1_INITFIRST_SIZE + \
101		MSG_DF1_NOOPEN_SIZE + \
102		MSG_DF1_ORIGIN_SIZE + \
103		MSG_DF1_DIRECT_SIZE + \
104		MSG_DF1_TRANS_SIZE + \
105		MSG_DF1_INTERPOSE_SIZE + \
106		MSG_DF1_NODEFLIB_SIZE + \
107		MSG_DF1_NODUMP_SIZE + \
108		MSG_DF1_CONFALT_SIZE + \
109		MSG_DF1_ENDFILTEE_SIZE + \
110		MSG_DF1_DISPRELPND_SIZE + \
111		MSG_DF1_DISPRELDNE_SIZE + \
112		MSG_DF1_NODIRECT_SIZE + \
113		MSG_DF1_IGNMULDEF_SIZE + \
114		MSG_DF1_NOKSYMS_SIZE + \
115		MSG_DF1_NORELOC_SIZE + \
116		MSG_DF1_NOHDR_SIZE + \
117		CONV_INV_STRSIZE + MSG_GBL_CSQBRKT_SIZE
118
119const char *
120conv_dyn_flag1(Xword flags)
121{
122	static char	string[FLAG1SZ];
123	static Val_desc vda[] = {
124		{ DF_1_NOW,		MSG_ORIG(MSG_DF_ORIGIN) },
125		{ DF_1_GLOBAL,		MSG_ORIG(MSG_DF1_GLOBAL) },
126		{ DF_1_GROUP,		MSG_ORIG(MSG_DF1_GROUP) },
127		{ DF_1_NODELETE,	MSG_ORIG(MSG_DF1_NODELETE) },
128		{ DF_1_LOADFLTR,	MSG_ORIG(MSG_DF1_LOADFLTR) },
129		{ DF_1_INITFIRST,	MSG_ORIG(MSG_DF1_INITFIRST) },
130		{ DF_1_NOOPEN,		MSG_ORIG(MSG_DF1_NOOPEN) },
131		{ DF_1_ORIGIN,		MSG_ORIG(MSG_DF1_ORIGIN) },
132		{ DF_1_DIRECT,		MSG_ORIG(MSG_DF1_DIRECT) },
133		{ DF_1_TRANS,		MSG_ORIG(MSG_DF1_TRANS) },
134		{ DF_1_INTERPOSE,	MSG_ORIG(MSG_DF1_INTERPOSE) },
135		{ DF_1_NODEFLIB,	MSG_ORIG(MSG_DF1_NODEFLIB) },
136		{ DF_1_NODUMP,		MSG_ORIG(MSG_DF1_NODUMP) },
137		{ DF_1_CONFALT,		MSG_ORIG(MSG_DF1_CONFALT) },
138		{ DF_1_ENDFILTEE,	MSG_ORIG(MSG_DF1_ENDFILTEE) },
139		{ DF_1_DISPRELPND,	MSG_ORIG(MSG_DF1_DISPRELPND) },
140		{ DF_1_DISPRELDNE,	MSG_ORIG(MSG_DF1_DISPRELDNE) },
141		{ DF_1_NODIRECT,	MSG_ORIG(MSG_DF1_NODIRECT) },
142		{ DF_1_IGNMULDEF,	MSG_ORIG(MSG_DF1_IGNMULDEF) },
143		{ DF_1_NOKSYMS,		MSG_ORIG(MSG_DF1_NOKSYMS) },
144		{ DF_1_NORELOC,		MSG_ORIG(MSG_DF1_NORELOC) },
145		{ DF_1_NOHDR,		MSG_ORIG(MSG_DF1_NOHDR) },
146		{ 0,			0 }
147	};
148
149	if (flags == 0)
150		return (MSG_ORIG(MSG_GBL_ZERO));
151
152	(void) strlcpy(string, MSG_ORIG(MSG_GBL_OSQBRKT), FLAG1SZ);
153	if (conv_expn_field(string, FLAG1SZ, vda, flags, flags, 0, 0))
154		(void) strlcat(string, MSG_ORIG(MSG_GBL_CSQBRKT), FLAG1SZ);
155
156	return ((const char *)string);
157}
158
159#define	FEATSZ	MSG_GBL_OSQBRKT_SIZE + \
160		MSG_DTF_PARINIT_SIZE + \
161		MSG_DTF_CONFEXP_SIZE + \
162		CONV_INV_STRSIZE + MSG_GBL_CSQBRKT_SIZE
163
164const char *
165conv_dyn_feature1(Xword flags)
166{
167	static char	string[FEATSZ];
168	static Val_desc vda[] = {
169		{ DTF_1_PARINIT,	MSG_ORIG(MSG_DTF_PARINIT) },
170		{ DTF_1_CONFEXP,	MSG_ORIG(MSG_DTF_CONFEXP) },
171		{ 0,			0 }
172	};
173
174	if (flags == 0)
175		return (MSG_ORIG(MSG_GBL_ZERO));
176
177	(void) strlcpy(string, MSG_ORIG(MSG_GBL_OSQBRKT), FEATSZ);
178	if (conv_expn_field(string, FEATSZ, vda, flags, flags, 0, 0))
179		(void) strlcat(string, MSG_ORIG(MSG_GBL_CSQBRKT), FEATSZ);
180
181	return ((const char *)string);
182}
183
184const char *
185conv_dyn_tag(Xword tag, Half mach)
186{
187	static char		string[CONV_INV_STRSIZE];
188	static const Msg	tags[DT_MAXPOSTAGS] = {
189		MSG_DYN_NULL,		MSG_DYN_NEEDED,
190		MSG_DYN_PLTRELSZ,	MSG_DYN_PLTGOT,
191		MSG_DYN_HASH,		MSG_DYN_STRTAB,
192		MSG_DYN_SYMTAB,		MSG_DYN_RELA,
193		MSG_DYN_RELASZ,		MSG_DYN_RELAENT,
194		MSG_DYN_STRSZ,		MSG_DYN_SYMENT,
195		MSG_DYN_INIT,		MSG_DYN_FINI,
196		MSG_DYN_SONAME,		MSG_DYN_RPATH,
197		MSG_DYN_SYMBOLIC,	MSG_DYN_REL,
198		MSG_DYN_RELSZ,		MSG_DYN_RELENT,
199		MSG_DYN_PLTREL,		MSG_DYN_DEBUG,
200		MSG_DYN_TEXTREL,	MSG_DYN_JMPREL,
201		MSG_DYN_BIND_NOW,	MSG_DYN_INIT_ARRAY,
202		MSG_DYN_FINI_ARRAY,	MSG_DYN_INIT_ARRAYSZ,
203		MSG_DYN_FINI_ARRAYSZ,	MSG_DYN_RUNPATH,
204		MSG_DYN_FLAGS,		MSG_DYN_NULL,
205		MSG_DYN_PREINIT_ARRAY,	MSG_DYN_PREINIT_ARRAYSZ
206	};
207
208	if (tag < DT_MAXPOSTAGS) {
209		/*
210		 * Generic dynamic tags.
211		 */
212		return (MSG_ORIG(tags[tag]));
213	} else {
214		/*
215		 * SUNW: DT_LOOS -> DT_HIOS range.
216		 */
217		if (tag == DT_SUNW_AUXILIARY)
218			return (MSG_ORIG(MSG_DYN_SUNW_AUXILIARY));
219		else if (tag == DT_SUNW_RTLDINF)
220			return (MSG_ORIG(MSG_DYN_SUNW_RTLDINF));
221		else if (tag == DT_SUNW_FILTER)
222			return (MSG_ORIG(MSG_DYN_SUNW_FILTER));
223		else if (tag == DT_SUNW_CAP)
224			return (MSG_ORIG(MSG_DYN_SUNW_CAP));
225
226		/*
227		 * SUNW: DT_VALRNGLO - DT_VALRNGHI range.
228		 */
229		else if (tag == DT_CHECKSUM)
230			return (MSG_ORIG(MSG_DYN_CHECKSUM));
231		else if (tag == DT_PLTPADSZ)
232			return (MSG_ORIG(MSG_DYN_PLTPADSZ));
233		else if (tag == DT_MOVEENT)
234			return (MSG_ORIG(MSG_DYN_MOVEENT));
235		else if (tag == DT_MOVESZ)
236			return (MSG_ORIG(MSG_DYN_MOVESZ));
237		else if (tag == DT_FEATURE_1)
238			return (MSG_ORIG(MSG_DYN_FEATURE_1));
239		else if (tag == DT_POSFLAG_1)
240			return (MSG_ORIG(MSG_DYN_POSFLAG_1));
241		else if (tag == DT_SYMINSZ)
242			return (MSG_ORIG(MSG_DYN_SYMINSZ));
243		else if (tag == DT_SYMINENT)
244			return (MSG_ORIG(MSG_DYN_SYMINENT));
245
246		/*
247		 * SUNW: DT_ADDRRNGLO - DT_ADDRRNGHI range.
248		 */
249		else if (tag == DT_CONFIG)
250			return (MSG_ORIG(MSG_DYN_CONFIG));
251		else if (tag == DT_DEPAUDIT)
252			return (MSG_ORIG(MSG_DYN_DEPAUDIT));
253		else if (tag == DT_AUDIT)
254			return (MSG_ORIG(MSG_DYN_AUDIT));
255		else if (tag == DT_PLTPAD)
256			return (MSG_ORIG(MSG_DYN_PLTPAD));
257		else if (tag == DT_MOVETAB)
258			return (MSG_ORIG(MSG_DYN_MOVETAB));
259		else if (tag == DT_SYMINFO)
260			return (MSG_ORIG(MSG_DYN_SYMINFO));
261
262		/*
263		 * SUNW: generic range.
264		 */
265		else if (tag == DT_VERSYM)
266			return (MSG_ORIG(MSG_DYN_VERSYM));
267		else if (tag == DT_RELACOUNT)
268			return (MSG_ORIG(MSG_DYN_RELACOUNT));
269		else if (tag == DT_RELCOUNT)
270			return (MSG_ORIG(MSG_DYN_RELCOUNT));
271		else if (tag == DT_FLAGS_1)
272			return (MSG_ORIG(MSG_DYN_FLAGS_1));
273		else if (tag == DT_VERDEF)
274			return (MSG_ORIG(MSG_DYN_VERDEF));
275		else if (tag == DT_VERDEFNUM)
276			return (MSG_ORIG(MSG_DYN_VERDEFNUM));
277		else if (tag == DT_VERNEED)
278			return (MSG_ORIG(MSG_DYN_VERNEED));
279		else if (tag == DT_VERNEEDNUM)
280			return (MSG_ORIG(MSG_DYN_VERNEEDNUM));
281		else if (tag == DT_AUXILIARY)
282			return (MSG_ORIG(MSG_DYN_AUXILIARY));
283		else if (tag == DT_USED)
284			return (MSG_ORIG(MSG_DYN_USED));
285		else if (tag == DT_FILTER)
286			return (MSG_ORIG(MSG_DYN_FILTER));
287
288		/*
289		 * SUNW: machine specific range.
290		 */
291		else if (((mach == EM_SPARC) || (mach == EM_SPARCV9) ||
292		    (mach == EM_SPARC32PLUS)) && (tag == DT_SPARC_REGISTER))
293			/* this is so x86 can display a sparc binary */
294			return (MSG_ORIG(MSG_DYN_REGISTER));
295		else if (tag == DT_DEPRECATED_SPARC_REGISTER)
296			return (MSG_ORIG(MSG_DYN_REGISTER));
297		else
298			return (conv_invalid_val(string, CONV_INV_STRSIZE,
299			    tag, 0));
300	}
301}
302
303#define	BINDTSZ	MSG_GBL_OSQBRKT_SIZE + \
304		MSG_BND_NEEDED_SIZE + \
305		MSG_BND_REFER_SIZE + \
306		MSG_BND_FILTER_SIZE + \
307		CONV_INV_STRSIZE + MSG_GBL_CSQBRKT_SIZE
308
309const char *
310conv_bnd_type(uint_t flags)
311{
312	static char	string[BINDTSZ];
313	static Val_desc vda[] = {
314		{ BND_NEEDED,		MSG_ORIG(MSG_BND_NEEDED) },
315		{ BND_REFER,		MSG_ORIG(MSG_BND_REFER) },
316		{ BND_FILTER,		MSG_ORIG(MSG_BND_FILTER) },
317		{ 0,			0 }
318	};
319
320	if (flags == 0)
321		return (MSG_ORIG(MSG_STR_EMPTY));
322
323	(void) strlcpy(string, MSG_ORIG(MSG_GBL_OSQBRKT), BINDTSZ);
324	if (conv_expn_field(string, BINDTSZ, vda, flags, flags, 0, 0))
325		(void) strlcat(string, MSG_ORIG(MSG_GBL_CSQBRKT), BINDTSZ);
326
327	return ((const char *)string);
328}
329
330#define	BINDOSZ	MSG_GBL_OSQBRKT_SIZE + \
331		MSG_BND_ADDED_SIZE + \
332		MSG_BND_REEVAL_SIZE + \
333		MSG_GBL_CSQBRKT_SIZE
334
335const char *
336conv_bnd_obj(uint_t flags)
337{
338	static char	string[BINDOSZ];
339	static Val_desc vda[] = {
340		{ LML_FLG_OBJADDED,	MSG_ORIG(MSG_BND_ADDED) },
341		{ LML_FLG_OBJREEVAL,	MSG_ORIG(MSG_BND_REEVAL) },
342		{ LML_FLG_OBJDELETED,	MSG_ORIG(MSG_BND_DELETED) },
343		{ LML_FLG_ATEXIT,	MSG_ORIG(MSG_BND_ATEXIT) },
344		{ 0,			0 }
345	};
346
347	if (flags == 0)
348		return (MSG_ORIG(MSG_STR_EMPTY));
349
350	/*
351	 * Note, we're not worried about unknown flags for this family, only
352	 * the selected flags are of interest.
353	 */
354	(void) strlcpy(string, MSG_ORIG(MSG_GBL_OSQBRKT), BINDOSZ);
355	if (conv_expn_field(string, BINDOSZ, vda, flags, 0, 0, 0))
356		(void) strlcat(string, MSG_ORIG(MSG_GBL_CSQBRKT), BINDOSZ);
357
358	return ((const char *)string);
359}
360