xref: /illumos-gate/usr/src/cmd/sgs/libconv/common/dynamic.c (revision 032624d56c174c5c55126582b32e314a6af15522)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 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 		MSG_GBL_CSQBRKT_SIZE
42 
43 const char *
44 conv_dynposflag_1_str(uint_t flags)
45 {
46 	static char	string[POSSZ] = { '\0' };
47 	if (flags == 0)
48 		return (MSG_ORIG(MSG_GBL_ZERO));
49 
50 	(void) strcpy(string, MSG_ORIG(MSG_GBL_OSQBRKT));
51 
52 	if (flags & DF_P1_LAZYLOAD)
53 		(void) strcat(string, MSG_ORIG(MSG_DFP_LAZYLOAD));
54 	if (flags & DF_P1_GROUPPERM)
55 		(void) strcat(string, MSG_ORIG(MSG_DFP_GROUPPERM));
56 
57 	(void) strcat(string, MSG_ORIG(MSG_GBL_CSQBRKT));
58 
59 	return ((const char *)string);
60 }
61 
62 #define	FLAGSZ	MSG_DF_ORIGIN_SIZE + \
63 		MSG_DF_SYMBOLIC_SIZE + \
64 		MSG_DF_TEXTREL_SIZE + \
65 		MSG_DF_BIND_NOW_SIZE + \
66 		MSG_DF_STATIC_TLS_SIZE
67 
68 const char *
69 conv_dynflag_str(uint_t flags)
70 {
71 	static char	string[FLAGSZ] = { '\0' };
72 	if (flags == 0)
73 		return (MSG_ORIG(MSG_GBL_ZERO));
74 	else {
75 		(void) strcpy(string, MSG_ORIG(MSG_GBL_OSQBRKT));
76 		if (flags & DF_ORIGIN)
77 			(void) strcat(string, MSG_ORIG(MSG_DF_ORIGIN));
78 		if (flags & DF_SYMBOLIC)
79 			(void) strcat(string, MSG_ORIG(MSG_DF_SYMBOLIC));
80 		if (flags & DF_TEXTREL)
81 			(void) strcat(string, MSG_ORIG(MSG_DF_TEXTREL));
82 		if (flags & DF_BIND_NOW)
83 			(void) strcat(string, MSG_ORIG(MSG_DF_BIND_NOW));
84 		if (flags & DF_STATIC_TLS)
85 			(void) strcat(string, MSG_ORIG(MSG_DF_STATIC_TLS));
86 
87 		(void) strcat(string, MSG_ORIG(MSG_GBL_CSQBRKT));
88 
89 		return ((const char *)string);
90 	}
91 }
92 
93 #define	FLAG1SZ	MSG_GBL_OSQBRKT_SIZE + \
94 		MSG_DF1_NOW_SIZE + \
95 		MSG_DF1_GROUP_SIZE + \
96 		MSG_DF1_NODELETE_SIZE + \
97 		MSG_DF1_LOADFLTR_SIZE + \
98 		MSG_DF1_INITFIRST_SIZE + \
99 		MSG_DF1_NOOPEN_SIZE + \
100 		MSG_DF1_ORIGIN_SIZE + \
101 		MSG_DF1_DIRECT_SIZE + \
102 		MSG_DF1_TRANS_SIZE + \
103 		MSG_DF1_INTERPOSE_SIZE + \
104 		MSG_DF1_NODEFLIB_SIZE + \
105 		MSG_DF1_NODUMP_SIZE + \
106 		MSG_DF1_CONFALT_SIZE + \
107 		MSG_DF1_ENDFILTEE_SIZE + \
108 		MSG_DF1_DISPRELPND_SIZE + \
109 		MSG_DF1_DISPRELDNE_SIZE + \
110 		MSG_DF1_NODIRECT_SIZE + \
111 		MSG_DF1_IGNMULDEF_SIZE + \
112 		MSG_DF1_NOKSYMS_SIZE + \
113 		MSG_DF1_NORELOC_SIZE + \
114 		MSG_GBL_CSQBRKT_SIZE
115 
116 const char *
117 conv_dynflag_1_str(uint_t flags)
118 {
119 	static char	string[FLAG1SZ] = { '\0' };
120 
121 	if (flags == 0)
122 		return (MSG_ORIG(MSG_GBL_ZERO));
123 	else {
124 		(void) strcpy(string, MSG_ORIG(MSG_GBL_OSQBRKT));
125 
126 		if (flags & DF_1_NOW)
127 			(void) strcat(string, MSG_ORIG(MSG_DF1_NOW));
128 		if (flags & DF_1_GROUP)
129 			(void) strcat(string, MSG_ORIG(MSG_DF1_GROUP));
130 		if (flags & DF_1_NODELETE)
131 			(void) strcat(string, MSG_ORIG(MSG_DF1_NODELETE));
132 		if (flags & DF_1_LOADFLTR)
133 			(void) strcat(string, MSG_ORIG(MSG_DF1_LOADFLTR));
134 		if (flags & DF_1_INITFIRST)
135 			(void) strcat(string, MSG_ORIG(MSG_DF1_INITFIRST));
136 		if (flags & DF_1_NOOPEN)
137 			(void) strcat(string, MSG_ORIG(MSG_DF1_NOOPEN));
138 		if (flags & DF_1_ORIGIN)
139 			(void) strcat(string, MSG_ORIG(MSG_DF1_ORIGIN));
140 		if (flags & DF_1_DIRECT)
141 			(void) strcat(string, MSG_ORIG(MSG_DF1_DIRECT));
142 		if (flags & DF_1_TRANS)
143 			(void) strcat(string, MSG_ORIG(MSG_DF1_TRANS));
144 		if (flags & DF_1_INTERPOSE)
145 			(void) strcat(string, MSG_ORIG(MSG_DF1_INTERPOSE));
146 		if (flags & DF_1_NODEFLIB)
147 			(void) strcat(string, MSG_ORIG(MSG_DF1_NODEFLIB));
148 		if (flags & DF_1_NODUMP)
149 			(void) strcat(string, MSG_ORIG(MSG_DF1_NODUMP));
150 		if (flags & DF_1_CONFALT)
151 			(void) strcat(string, MSG_ORIG(MSG_DF1_CONFALT));
152 		if (flags & DF_1_ENDFILTEE)
153 			(void) strcat(string, MSG_ORIG(MSG_DF1_ENDFILTEE));
154 		if (flags & DF_1_DISPRELPND)
155 			(void) strcat(string, MSG_ORIG(MSG_DF1_DISPRELPND));
156 		if (flags & DF_1_DISPRELDNE)
157 			(void) strcat(string, MSG_ORIG(MSG_DF1_DISPRELDNE));
158 		if (flags & DF_1_NODIRECT)
159 			(void) strcat(string, MSG_ORIG(MSG_DF1_NODIRECT));
160 		if (flags & DF_1_IGNMULDEF)
161 			(void) strcat(string, MSG_ORIG(MSG_DF1_IGNMULDEF));
162 		if (flags & DF_1_NOKSYMS)
163 			(void) strcat(string, MSG_ORIG(MSG_DF1_NOKSYMS));
164 		if (flags & DF_1_NORELOC)
165 			(void) strcat(string, MSG_ORIG(MSG_DF1_NORELOC));
166 
167 		(void) strcat(string, MSG_ORIG(MSG_GBL_CSQBRKT));
168 
169 		return ((const char *)string);
170 	}
171 }
172 
173 #define	FEATSZ	MSG_GBL_OSQBRKT_SIZE + \
174 		MSG_DTF_PARINIT_SIZE + \
175 		MSG_DTF_CONFEXP_SIZE + \
176 		MSG_GBL_CSQBRKT_SIZE
177 
178 const char *
179 conv_dynfeature_1_str(uint_t flags)
180 {
181 	static char	string[FEATSZ] = { '\0' };
182 
183 	if (flags == 0)
184 		return (MSG_ORIG(MSG_GBL_ZERO));
185 	else {
186 		(void) strcpy(string, MSG_ORIG(MSG_GBL_OSQBRKT));
187 
188 		if (flags & DTF_1_PARINIT)
189 			(void) strcat(string, MSG_ORIG(MSG_DTF_PARINIT));
190 		if (flags & DTF_1_CONFEXP)
191 			(void) strcat(string, MSG_ORIG(MSG_DTF_CONFEXP));
192 
193 		(void) strcat(string, MSG_ORIG(MSG_GBL_CSQBRKT));
194 
195 		return ((const char *)string);
196 	}
197 }
198 
199 const Msg _dyntag_tags[DT_MAXPOSTAGS] = {
200 	MSG_DYN_NULL,		MSG_DYN_NEEDED,		MSG_DYN_PLTRELSZ,
201 	MSG_DYN_PLTGOT,		MSG_DYN_HASH,		MSG_DYN_STRTAB,
202 	MSG_DYN_SYMTAB,		MSG_DYN_RELA,		MSG_DYN_RELASZ,
203 	MSG_DYN_RELAENT,	MSG_DYN_STRSZ,		MSG_DYN_SYMENT,
204 	MSG_DYN_INIT,		MSG_DYN_FINI,		MSG_DYN_SONAME,
205 	MSG_DYN_RPATH,		MSG_DYN_SYMBOLIC,	MSG_DYN_REL,
206 	MSG_DYN_RELSZ,		MSG_DYN_RELENT,		MSG_DYN_PLTREL,
207 	MSG_DYN_DEBUG,		MSG_DYN_TEXTREL,	MSG_DYN_JMPREL,
208 	MSG_DYN_BIND_NOW,	MSG_DYN_INIT_ARRAY,	MSG_DYN_FINI_ARRAY,
209 	MSG_DYN_INIT_ARRAYSZ,	MSG_DYN_FINI_ARRAYSZ,	MSG_DYN_RUNPATH,
210 	MSG_DYN_FLAGS,		MSG_DYN_NULL,		MSG_DYN_PREINIT_ARRAY,
211 	MSG_DYN_PREINIT_ARRAYSZ
212 };
213 
214 const char *
215 conv_dyntag_str(uint64_t tag, ushort_t mach)
216 {
217 	static char	string[STRSIZE] = { '\0' };
218 
219 	if (tag < DT_MAXPOSTAGS) {
220 		/*
221 		 * Generic dynamic tags.
222 		 */
223 		return (MSG_ORIG(_dyntag_tags[tag]));
224 	} else {
225 		/*
226 		 * SUNW: DT_LOOS -> DT_HIOS range.
227 		 */
228 		if (tag == DT_SUNW_AUXILIARY)
229 			return (MSG_ORIG(MSG_DYN_SUNW_AUXILIARY));
230 		else if (tag == DT_SUNW_RTLDINF)
231 			return (MSG_ORIG(MSG_DYN_SUNW_RTLDINF));
232 		else if (tag == DT_SUNW_FILTER)
233 			return (MSG_ORIG(MSG_DYN_SUNW_FILTER));
234 		else if (tag == DT_SUNW_CAP)
235 			return (MSG_ORIG(MSG_DYN_SUNW_CAP));
236 
237 		/*
238 		 * SUNW: DT_VALRNGLO - DT_VALRNGHI range.
239 		 */
240 		else if (tag == DT_CHECKSUM)
241 			return (MSG_ORIG(MSG_DYN_CHECKSUM));
242 		else if (tag == DT_PLTPADSZ)
243 			return (MSG_ORIG(MSG_DYN_PLTPADSZ));
244 		else if (tag == DT_MOVEENT)
245 			return (MSG_ORIG(MSG_DYN_MOVEENT));
246 		else if (tag == DT_MOVESZ)
247 			return (MSG_ORIG(MSG_DYN_MOVESZ));
248 		else if (tag == DT_FEATURE_1)
249 			return (MSG_ORIG(MSG_DYN_FEATURE_1));
250 		else if (tag == DT_POSFLAG_1)
251 			return (MSG_ORIG(MSG_DYN_POSFLAG_1));
252 		else if (tag == DT_SYMINSZ)
253 			return (MSG_ORIG(MSG_DYN_SYMINSZ));
254 		else if (tag == DT_SYMINENT)
255 			return (MSG_ORIG(MSG_DYN_SYMINENT));
256 
257 		/*
258 		 * SUNW: DT_ADDRRNGLO - DT_ADDRRNGHI range.
259 		 */
260 		else if (tag == DT_CONFIG)
261 			return (MSG_ORIG(MSG_DYN_CONFIG));
262 		else if (tag == DT_DEPAUDIT)
263 			return (MSG_ORIG(MSG_DYN_DEPAUDIT));
264 		else if (tag == DT_AUDIT)
265 			return (MSG_ORIG(MSG_DYN_AUDIT));
266 		else if (tag == DT_PLTPAD)
267 			return (MSG_ORIG(MSG_DYN_PLTPAD));
268 		else if (tag == DT_MOVETAB)
269 			return (MSG_ORIG(MSG_DYN_MOVETAB));
270 		else if (tag == DT_SYMINFO)
271 			return (MSG_ORIG(MSG_DYN_SYMINFO));
272 
273 		/*
274 		 * SUNW: generic range.
275 		 */
276 		else if (tag == DT_VERSYM)
277 			return (MSG_ORIG(MSG_DYN_VERSYM));
278 		else if (tag == DT_RELACOUNT)
279 			return (MSG_ORIG(MSG_DYN_RELACOUNT));
280 		else if (tag == DT_RELCOUNT)
281 			return (MSG_ORIG(MSG_DYN_RELCOUNT));
282 		else if (tag == DT_FLAGS_1)
283 			return (MSG_ORIG(MSG_DYN_FLAGS_1));
284 		else if (tag == DT_VERDEF)
285 			return (MSG_ORIG(MSG_DYN_VERDEF));
286 		else if (tag == DT_VERDEFNUM)
287 			return (MSG_ORIG(MSG_DYN_VERDEFNUM));
288 		else if (tag == DT_VERNEED)
289 			return (MSG_ORIG(MSG_DYN_VERNEED));
290 		else if (tag == DT_VERNEEDNUM)
291 			return (MSG_ORIG(MSG_DYN_VERNEEDNUM));
292 		else if (tag == DT_AUXILIARY)
293 			return (MSG_ORIG(MSG_DYN_AUXILIARY));
294 		else if (tag == DT_USED)
295 			return (MSG_ORIG(MSG_DYN_USED));
296 		else if (tag == DT_FILTER)
297 			return (MSG_ORIG(MSG_DYN_FILTER));
298 
299 		/*
300 		 * SUNW: machine specific range.
301 		 */
302 		else if (((mach == EM_SPARC) || (mach == EM_SPARCV9) ||
303 		    (mach == EM_SPARC32PLUS)) && (tag == DT_SPARC_REGISTER))
304 			/* this is so x86 can display a sparc binary */
305 			return (MSG_ORIG(MSG_DYN_REGISTER));
306 		else if (tag == DT_DEPRECATED_SPARC_REGISTER)
307 			return (MSG_ORIG(MSG_DYN_REGISTER));
308 		else
309 			return (conv_invalid_str(string, STRSIZE, tag, 0));
310 	}
311 }
312 
313 #define	BINDESZ	MSG_GBL_OSQBRKT_SIZE + \
314 		MSG_BND_NEEDED_SIZE + \
315 		MSG_BND_REFER_SIZE + \
316 		MSG_BND_FILTER_SIZE + \
317 		MSG_GBL_CSQBRKT_SIZE
318 
319 const char *
320 conv_bindent_str(uint_t flags)
321 {
322 	static char	string[BINDESZ] = { '\0' };
323 
324 	/*
325 	 * Evaluate the binding descriptors flags.
326 	 */
327 	if (flags) {
328 		(void) strcpy(string, MSG_ORIG(MSG_GBL_OSQBRKT));
329 		if (flags & BND_NEEDED)
330 			(void) strcat(string, MSG_ORIG(MSG_BND_NEEDED));
331 		if (flags & BND_REFER)
332 			(void) strcat(string, MSG_ORIG(MSG_BND_REFER));
333 		if (flags & BND_FILTER)
334 			(void) strcat(string, MSG_ORIG(MSG_BND_FILTER));
335 		(void) strcat(string, MSG_ORIG(MSG_GBL_CSQBRKT));
336 
337 		return ((const char *)string);
338 	} else
339 		return (MSG_ORIG(MSG_STR_EMPTY));
340 }
341 
342 #define	BINDSSZ	MSG_GBL_OSQBRKT_SIZE + \
343 		MSG_BND_ADDED_SIZE + \
344 		MSG_BND_REEVAL_SIZE + \
345 		MSG_GBL_CSQBRKT_SIZE
346 
347 const char *
348 conv_binding_str(uint_t flags)
349 {
350 	static char	string[BINDSSZ] = { '\0' };
351 
352 	/*
353 	 * Evaluate the binding descriptors flags.
354 	 */
355 	if (flags) {
356 		(void) strcpy(string, MSG_ORIG(MSG_GBL_OSQBRKT));
357 		if (flags & LML_FLG_OBJADDED)
358 			(void) strcat(string, MSG_ORIG(MSG_BND_ADDED));
359 		if (flags & LML_FLG_OBJREEVAL)
360 			(void) strcat(string, MSG_ORIG(MSG_BND_REEVAL));
361 		if (flags & LML_FLG_OBJDELETED)
362 			(void) strcat(string, MSG_ORIG(MSG_BND_DELETED));
363 		if (flags & LML_FLG_ATEXIT)
364 			(void) strcat(string, MSG_ORIG(MSG_BND_ATEXIT));
365 		(void) strcat(string, MSG_ORIG(MSG_GBL_CSQBRKT));
366 
367 		return ((const char *)string);
368 	} else
369 		return (MSG_ORIG(MSG_STR_EMPTY));
370 }
371